Results
Results are now for eight species managed under Mid-Atlantic Council Management Plans according to NOAA.
Scomber scombrus, Peprilus triacanthus (butterfish), Illex illecebrosus (shortfin squid), Paralichthys dentatus (summer flounder), Stenotomus chrysops (Scoop), Centropristis striata (black sea bass), Pomatomus saltatrix (Bluefish), Lopholatilus chamaeleonticeps (Golden tilefish), Caulolatilus microps (blueline tilefish) and Clupea harengus
state_lat <- historic_spp %>%
group_by(state) %>%
summarise(
order = mean(lat)
) %>%
mutate(abrev = c("CT","DE","ME","MD","MA","NH","NJ","NY","NC","RI","VA")
) %>%
arrange(desc(order)) %>%
mutate(order= letters[1:11])
Error in group_by(., state) : object 'historic_spp' not found
Average proportion
This map shows the aggregated extrapolated value from all three species per State average across the whole study period within each State’s water.
Note: This is intended to be a supplemental figure
data_grid <- historic_spp %>%
group_by(state,lat,lon,region) %>%
summarise(sum = sum(value,na.rm= T), .groups = "drop") %>% # sum of all species
group_by(state,lat,lon,region) %>%
summarise(mean = mean(sum,na.rm= T), .groups = "drop") # average of all years
ggplot(data = subset(data_grid, !is.na(mean))) +
geom_tile(
aes(
x = lon,
y = lat,
fill = mean,
col = mean
)
) +
geom_sf(data = land_sf, aes()) +
facet_wrap(~ state + region,
ncol = 4) +
labs(x = "Longitude", y = "Latitude") +
scale_fill_viridis("Mean Interpolation", alpha = 0.8) +
scale_color_viridis("Mean Interpolation", alpha = 0.8) +
theme_bw()
Proportion Change
Here we show the average proportion of the interpolation by State and time period. Time periods were arbitrary defined as;
- Early; 1973 to 1984
- Mid; 1985 to 1997
- Late; 1998 to 2011
- Now; 2012 to 2019
Notes: Figure represents the Spring survey. This computation considers the Overlapping of state waters.
Area plot
This graph shows the proportion of the interpolation value each State has over time.
Note: This plot is interactive. For ease comparison between States you can;
- One click on any State to remove it from the plot
- Two clicks on any State to isolate it from the plot (other states can then be added by just clicking on them).
- The bottom panel allows you to reduce the time frame
Dynamic aggregated plot
total_fited <- historic_spp %>%
group_by(year,region) %>%
summarise(total_value = sum(value,na.rm=T),.groups = "drop")
# group by state
state_fit <- historic_spp %>%
group_by(state,year,region) %>%
summarise(state_value = sum(value,na.rm= T), .groups = "drop") %>%
left_join(total_fited,
by = c("year","region")) %>%
mutate(percentage = state_value/total_value*100)
# Plot me
p <- ggplot(state_fit) +
geom_area(
aes(
x = year,
y = round(percentage),
fill = state
)
) +
ylab("Percentage (%)") +
# viridis::scale_fill_viridis(discrete = T, alpha = 0.8) +
scale_fill_manual(values = state_pallet) +
MyFunctions::my_ggtheme_p() +
facet_wrap(~region, ncol = 1) +
theme_dark()
ggplotly(p,
dynamicTicks = TRUE) %>%
layout(hovermode = "x") %>%
rangeslider()
Area plot (running mean)
This graph shows the proportion of each State smoothed over a *10 years running mean**. It allows to better see increasing and decreasing trends.
Dynamic aggregated plot
Note: This plot is also interactive and thus, follows the same options of the previous one.
# group by state
state_fit <- historic_spp %>%
group_by(state,year,region,.groups = "drop") %>%
summarise(state_value = sum(value,na.rm= T), .groups = "drop") %>%
left_join(total_fited,
by = c("year","region")) %>%
mutate(percentage = state_value/total_value*100) %>%
group_by(state,region) %>%
mutate(RMean = zoo::rollmean(x = percentage,
10,
fill = NA,
na.rm=T)
) %>%
left_join(state_lat)
# Plot me
p <- ggplot(state_fit) +
geom_area(
aes(
x = year,
y = round(RMean),
fill = state
# fill = order
)
) +
ylab("10 yrs running average (%)") +
scale_fill_manual(
"State",
values = state_pallet,
# labels = state_fit %>% arrange(order) %>% pull(state) %>% unique()
) +
MyFunctions::my_ggtheme_p() +
facet_wrap(~region, ncol = 1) +
theme_dark()
suppressWarnings(
ggplotly(p,
dynamicTicks = TRUE) %>%
layout(hovermode = "x") %>%
# add_trace() %>%
rangeslider()
)
Historic quota Vs distributions
This section of the results explores the differences between the historic distribution of te stock and the historic quota allocation. We collected the proportion of the total quota that each State gets for each species.
Right now the analysis only covers black sea bass, summer flounder and scup. But we can go speceis by species to see which ones have their quota allocated by state to include them in the analysis.
Note: We are using the new allocations based on the stock’s most recent biomass distribution*
For State-level managed species see the Atlantic States Marine Fisheries Comission website and go species-by-species.
quota_allocation <- state_lat %>%
mutate(
"Centropristis striata" = c(
0.0040, #ME
0.0040, #NH
0.1564, #MA
0.1323, #RI
0.0367, #CT
0.0857, #NY
0.2010, #NJ
0.0411, #DE
0.0888, #MD
0.1614, #VA
0.0888 #NC
),
"Paralichthys dentatus" = c(
0.0004756, #ME
0.0000046, #NH
0.0682046, #MA
0.1568298, #RI
0.0225708, #CT
0.0764699, #NY
0.1672499, #NJ
0.0001779, #DE
0.0203910, #MD
0.2131676, #VA
0.2744584 #NC
),
"Stenotomus chrysops" = c(
0.0012101, #ME
0.0000000, #HN
0.2158729, #MA
0.5619456, #RI
0.0315399, #CT
0.1582466, #NY
0.0291667, #NJ
0.0000000, #DE
0.0001190, #MD
0.0016502, #VA
0.0002490 #NC
)
) %>%
gather("spp","quota",4:6)
# Double check they all add to 1...
quota_allocation %>%
group_by(spp) %>%
summarise_at(vars(quota),sum)
quota_allocation %>%
arrange(order) %>%
select(-order) %>%
spread(spp,quota) %>%
kable()
Get data ready
total_fited <- historic_spp %>%
group_by(year,region,spp) %>%
summarise(total_value = sum(value,na.rm=T),.groups = "drop")
# group by state
state_fit <- historic_spp %>%
group_by(state,year,region,spp) %>%
summarise(state_value = sum(value,na.rm= T), .groups = "drop") %>%
left_join(total_fited,
by = c("year","region","spp")) %>%
mutate(percentage = state_value/total_value*100) %>%
#Only show results for spring
filter(str_detect(region,"Spring"))
quota_df <- quota_allocation %>%
left_join(historic_spp) %>%
group_by(state,abrev,year,region,spp,quota) %>%
summarise(state_value = sum(value,na.rm= T), .groups = "drop") %>%
left_join(total_fited,
by = c("year","region","spp")) %>%
mutate(Distribution = state_value/total_value*100,
Historic = quota*100) %>%
group_by(state,quota,spp) %>%
mutate(RMean = zoo::rollmean(x = Distribution,
10,
fill = NA,
na.rm=T)
) %>%
#Only show results for spring
filter(str_detect(region,"Spring"),
!is.na(RMean) # Remove NAs from rollmean
) %>%
left_join(state_lat) %>%
filter(
# spp =="Centropristis striata"
spp %in% quota_allocation$spp
)
head(quota_df) %>%
kable()
Exploring different ways to show the results
Difference line plot
This version shows the difference between the Historic quota allocation and the distribution proportion of the stock:
- diff < 0 = the distribution proportion is larger than the allocated quota
- diff > 0 = the distribution proportion is smaller than the allocated quota
# Option one
quota_df %>%
mutate(diff = Historic- Distribution,
diff_rmean = RMean- Distribution) %>%
gather("type","value",diff:diff_rmean) %>%
# View()
ggplot() +
geom_line(
aes(
x = year,
y = value,
color = order
)
) +
scale_color_manual("State",
values = state_pallet,
labels = quota_df %>% arrange(order) %>% pull(state) %>% unique()
) +
facet_grid(type~spp,
scales = "free") +
theme_dark()
Linetype plot
Here, we plot the distributional quota (solid lines) with each State’s allocation with dashed (—-) lines
# Option one
quota_df %>%
gather("level","quota",Distribution:RMean) %>%
# mutate(diff = quota_per- percentage) %>%
# View()
ggplot() +
geom_line(
aes(
x = year,
y = quota,
color = order
)
) +
labs(x = "Year",y = "Quota (%)") +
scale_fill_manual("State",
values = state_pallet,
labels = quota_df %>% arrange(order) %>% pull(state) %>% unique()
) +
scale_color_manual("State",
values = state_pallet,
labels = quota_df %>% arrange(order) %>% pull(state) %>% unique()
) +
scale_linetype("Quota") +
facet_grid(spp ~ level)+
theme_dark()
Efficiency index
The idea here is create and efficiency index (Danger!) that computes the alignment between the distribution and the actual allocation. The index is simply;
\[ei = \frac{HistoricQuota}{DistributionProportion}\] So, in cases where ei = 1, the quota is aligned with the distribution; when ei > 1 then the historic quota is more than the stock’s State’s distribution, contrarily, ei < 1 means that the historic quota is less than what the State currently has.
Note: - There are some crazzy outliers that have been removed, for now… - Bottom plot representing index as a Rmean
As a normal year to year
# Option one
eff_index <- quota_df %>%
# filter(
# spp =="Centropristis striata"
# ) %>%
mutate(index = Distribution/Historic,
index_rmean = RMean/Historic) %>%
gather("level","index",index:index_rmean) %>%
filter(index < 5) # there are some craaaazy outliers
# View()
ggplot(eff_index) +
geom_line(
aes(
x = year,
y = index,
color = state
),
) +
labs(x = "Year",y = "Efficiency index") +
scale_fill_manual("State",
values = state_pallet,
labels = quota_df %>% arrange(order) %>% pull(state) %>% unique()
) +
scale_color_manual("State",
values = state_pallet,
labels = quota_df %>% arrange(order) %>% pull(state) %>% unique()
) +
facet_grid(level~spp,
scales = "free")+
theme_dark()
LS0tCnRpdGxlOiAiU3BhdGlhbCBBbmFseXNpcyIKYXV0aG9yOiAiSnVsaWFubyBQYWxhY2lvcyBBYnJhbnRlcyIKb3V0cHV0OgogICMgaHRtbF9kb2N1bWVudAogIGh0bWxfbm90ZWJvb2s6CiAgICBmaWdfd2lkdGg6IDYKICAgIGZpZ19oZWlnaHQ6IDQKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICB0aGVtZTogZGFya2x5Ci0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoTXlGdW5jdGlvbnMpCk15RnVuY3Rpb25zOjpteV9saWIoYygiZ2dtYXAiLCJzZiIsInN0IiwidGlkeXZlcnNlIiwidG9vbHMiLCJyZWFkciIsImRhdGEudGFibGUiLCJtYXBzIiwidmlyaWRpcyIsIndlc2FuZGVyc29uIiwia25pdHIiLCJrYWJsZUV4dHJhIiwicGxvdGx5IiwiZ2dyZXBlbCIsImdnc2ZsYWJlbCIsImphbml0b3IiLCJpbnRlcnAiLCJybmF0dXJhbGVhcnRoIiwicmVhZHhsIikpCgojIEZpeCBuZXcgdXBkYXRzIG9mIHNmIHBhY2thZ2UKc2Y6OnNmX3VzZV9zMih1c2VfczIgPSBGQUxTRSkKCgojIENyZWF0ZSBzcGVjaWZpYyBzdGF0ZSBwYWxsZXQgZnJvbSBvdXIgZnJpZW5kIFdlcyBBbmRlcnNzb24Kc3RhdGVfcGFsbGV0IDwtIGMod2VzX3BhbGV0dGUobiA9IDUsIG5hbWUgPSAiRGFyamVlbGluZzEiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlc19wYWxldHRlKG4gPSA1LCBuYW1lID0gIkRhcmplZWxpbmcyIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZXNfcGFsZXR0ZShuID0gMywgbmFtZSA9ICJSb3lhbDEiKQogICAgICAgICAgICAgICAgICApCgpgYGAKCiMgTWV0aG9kcwoKIyMgU3BhdGlhbCBkYXRhIHByZXBhcmF0aW9uCgojIyMgTG9hZCBkYXRhCgojIyMjIE1hcHMgZGF0YQoKV2UgdXNlIHRocmVlIGRpZmZlcmVudCBzaGFwZWZpbGVzIGZvciB0aGUgY29udGluZW50YWwgVS5TLiBsYW5kIG1hc3MsIHRoZSBTdGF0ZSB3YXRlcnMgb2YgbWFpbmUsIG5ldyBoYW1wc2hpcmUsIG1hc3NhY2h1c2V0cywgY29ubmVjdGljdXQsIHJob2RlIGlzbGFuZCwgbmV3IHlvcmssIG5ldyBqZXJzZXksIGRlbGF3YXJlLCBtYXJ5bGFuZCwgdmlyZ2luaWEsIG5vcnRoIGNhcm9saW5hIGFuZCB0aGUgTm9ydGggRWFzdCBFRVouIE1vcmVvdmVyLCB3ZSB1c2UgdGhlIE5PQUEgZGF0YXNldCBvZiBsYW5kaW5ncyBwZXIgcG9ydC4KCiMjIyMjIDEuLSBMYW5kIHNoYXBlZmlsZQoKQ292ZXJzIHRoZSBVUyBsYW5kIHRlcnJpdG9yeSBmb3IgdmlzdWFsaXphdGlvbi4gRGF0YSBwcm92aWRlZCBmcm9tIHRoZSBgbWFwYCBwYWNrYWdlLgoKCmBgYHtyIGxhbmRfc2YsIGV2YWwgPSBULCBlY2hvID0gVCwgcmVzdWx0cyA9ICdoaWRlJ30KClN0YXRlcyA8LSBjKCJtYWluZSIsICJuZXcgaGFtcHNoaXJlIiwgIm1hc3NhY2h1c2V0dHMiLCAiY29ubmVjdGljdXQiLCAicmhvZGUgaXNsYW5kIiwgIm5ldyB5b3JrIiwgIm5ldyBqZXJzZXkiLCAiZGVsYXdhcmUiLCAibWFyeWxhbmQiLCAidmlyZ2luaWEiLCAibm9ydGggY2Fyb2xpbmEiKSAKCiMgLS0tLS0tLS0tLS0tLS0gIwojIFVTIFN0YXRlIE1hcCAobGFuZCkKIyAtLS0tLS0tLS0tLS0tLSAjCgpsYW5kX3NmIDwtIHN0X2FzX3NmKG1hcCgic3RhdGUiLCBwbG90ID0gRkFMU0UsIGZpbGwgPSBUUlVFKSkgJT4lIAogIGZpbHRlcihJRCAlaW4lIFN0YXRlcykgJT4lIAogIG11dGF0ZShhYnJldiA9IGMoIkNUIiwiREUiLCJNRSIsIk1EIiwiTUEiLCJOSCIsIk5KIiwiTlkiLCJOQyIsIlJJIiwiVkEiKSwKICAgICAgICAgc3RhdGUgPSBzdHJfdG9fc2VudGVuY2UoSUQpCiAgICAgICAgICkKCiMgVmlzdWFsIGV4cGxvcmF0aW9uIChvLmshICkKZ2dwbG90KGxhbmRfc2YpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gc3RhdGUpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgdGhlbWVfZGFyaygpCiAgICAgICAgICAKCmBgYAoKIyMjIyMgIDIuLSBFRVogc2hhcGVmaWxlCgpVc2VkIHRoZSAqU2VhIEFyb3VuZCBVcyogc2hhcGVmbGUgdXBkYXRlZCB0byBKdW5lIDIwMTYuCgpgYGB7ciBlZXpfc2YsIGV2YWwgPSBULCBlY2hvID0gVH0KCiMgVVMgRUVaIG1hcApwYXRoX3dvcmxkIDwtIG15X3BhdGgoIkciLCBleHRyYV9wYXRoID0gIlNwYXRpYWwvU0FVL1NBVV9TaGFwZWZpbGUiLCBuYW1lID0gIlNBVUVFWl9KdWx5MjAxNS5zaHAiKQoKIyBMb2FkIGl0IQplZXpfc2YgPC0gc3RfcmVhZChwYXRoX3dvcmxkKSAlPiUKICByZW5hbWUoZWV6X25hbWUgPSBOYW1lKSAlPiUKICBzdF90cmFuc2Zvcm0oY3JzID0gNDMyNikgJT4lICMgNDMyNgogIGZpbHRlcihlZXpfbmFtZSA9PSAiVVNBIChFYXN0IENvYXN0KSIpICU+JQogIHN0X3NpbXBsaWZ5KHByZXNlcnZlVG9wb2xvZ3kgPSBUUlVFLCBkVG9sZXJhbmNlID0gMC4xKSAjMC4xIGZvciBwYXBlcgoKIyBWaXN1YWwgZXhwbG9yYXRpb24gKG8uayEgKQpnZ3Bsb3QoZWV6X3NmKSArCiAgZ2VvbV9zZigpICsKICB0aGVtZV9kYXJrKCkKCmBgYAoKIyMjIyMgIDMuLSAgU3RhdGUgd2F0ZXJzCgpDb3ZlcnMgdGhlIHN0YXRlIHdhdGVycyBvZiB0aGUgTkUgVVMgc3RhdGVzLiBEYXRhIGZyb20gW2RhdGEuZ292XShodHRwczovL2NhdGFsb2cuZGF0YS5nb3YvZGF0YXNldC9mZWRlcmFsLWFuZC1zdGF0ZS13YXRlcnMpLiAgCgoqTGljZW5zZTogTm8gbGljZW5zZSBpbmZvcm1hdGlvbiB3YXMgcHJvdmlkZWQuIElmIHRoaXMgd29yayB3YXMgcHJlcGFyZWQgYnkgYW4gb2ZmaWNlciBvciBlbXBsb3llZSBvZiB0aGUgVW5pdGVkIFN0YXRlcyBnb3Zlcm5tZW50IGFzIHBhcnQgb2YgdGhhdCBwZXJzb24ncyBvZmZpY2lhbCBkdXRpZXMgaXQgaXMgY29uc2lkZXJlZCBhIFUuUy4gR292ZXJubWVudCBXb3JrLioKCmBgYHtyIHN0YXRlX3NmLCBldmFsID0gVCwgZWNobyA9IFR9CgojIHVzX3N0YXRlX2ZpbGUgPC0gbXlfcGF0aCgiRyIsIGV4dHJhX3BhdGggPSAiU3BhdGlhbC9VU0ZlZEFuZFN0YXRlVy9GZWRlcmFsQW5kU3RhdGVXYXRlcnMuZ2RiIikKCnN0YXRlX3NmIDwtICBzdF9yZWFkKCJ+L09uZURyaXZlIC0gVVctTWFkaXNvbi9TcGF0aWFsX0RhdGEvVVNGZWRBbmRTdGF0ZVcvRmVkZXJhbEFuZFN0YXRlV2F0ZXJzLmdkYiIpICU+JQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lIAogIG11dGF0ZShqdXJpc2RpY3RpID0gc3RyX3RvX2xvd2VyKGp1cmlzZGljdGkpKSAlPiUgCiAgZmlsdGVyKGp1cmlzZGljdGkgJWluJSBTdGF0ZXMpICU+JSAKICBtdXRhdGUoc3RhdGUgPSBzdHJfdG9fc2VudGVuY2UoanVyaXNkaWN0aSkpICU+JSAKICBzdF90cmFuc2Zvcm0oY3JzID0gNDMyNikgJT4lICAgIyBmb3IgbWF0Y2hpbmcgcHJvamVjdGlvbnMKICBzdF9zaW1wbGlmeShwcmVzZXJ2ZVRvcG9sb2d5ID0gVFJVRSwgZFRvbGVyYW5jZSA9IDEwMDAwKSAjMC4xIGZvciBwYXBlcgoKCiMgVmlzdWFsIGV4cGxvcmF0aW9uIChvLmshICkKZ2dwbG90KHN0YXRlX3NmKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IHN0YXRlKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogIHRoZW1lX2RhcmsoKQoKYGBgCgojIyMjIyA0Li0gRmlzaGluZyBwb3J0cwoKV2UgdXNlZCBbR2xvYmFsIEZpc2hpbmcgV2F0Y2hdKGh0dHBzOi8vZ2xvYmFsZmlzaGluZ3dhdGNoLm9yZy9kYXRhc2V0cy1hbmQtY29kZS1hbmNob3JhZ2VzLykncyBkYXRhYmFzZSBvbiAKQW5jaG9yYWdlcywgUG9ydHMgYW5kIFZveWFnZXMuCgoqVGhlIEdsb2JhbCBGaXNoaW5nIFdhdGNoIGFuY2hvcmFnZXMgZGF0YXNldCBpcyBhIGdsb2JhbCBkYXRhYmFzZSBvZiBhbmNob3JhZ2UgbG9jYXRpb25zIHdoZXJlIHZlc3NlbHMgY29uZ3JlZ2F0ZS4gVGhlIGRhdGFzZXQgY29udGFpbnMgb3ZlciAxNjAsMDAwIGluZGl2aWR1YWwgYW5jaG9yYWdlIGxvY2F0aW9ucywgd2hpY2ggYXJlIGZ1cnRoZXIgZ3JvdXBlZCBpbnRvIG5lYXJseSAzMiwwMDAgcG9ydHMgd2hlbiBhcHBsaWNhYmxlLioKCgpgYGB7ciBwb3J0c19zZiwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKIyBHZXQgR2xvYmFsIEZpc2hpZyBXYXRjaCBkYXRhCmdmd19kYXRhIDwtIG15X3BhdGgoIkQiLCJTcGF0aWFsIixuYW1lID0gImdmd19wb3J0ZGF0YS5jc3YiLCByZWFkID0gVCkgJT4lIAogIGZpbHRlcihpc28zID09ICJVU0EiKSAKCiMgVmlzdWFsaXplIGRhdGEgKG8uayEpCiMgZ2dwbG90KGdmd19kYXRhKSArCiMgICBnZW9tX3BvaW50KAojICAgICBhZXMoCiMgICAgIHggPSBsb24sCiMgICAgIHkgPSBsYXQKIyAgICkKIyAgICkKCiMgQ29udmVydCBkYXRhIHRvIHNmIGZvciBtZXJnaWcKZ2Z3X3NmIDwtIHN0X2FzX3NmKGdmd19kYXRhLAogICAgICAgICAgICAgY29vcmRzID0gYygibG9uIiwgImxhdCIpLAogICAgICAgICAgICAgY3JzID0gNDMyNikKCiMgTWVyZ2UgZGF0YSB3aXRoIHN0YXRlIHdhdGVycyB0byxsb2NhdGUgcG9ydHMgCnBvcnRfc2YgPC0gc3Rfam9pbihnZndfc2Ysc3RhdGVfc2YpICU+JSAKICBmaWx0ZXIoIWlzLm5hKGp1cmlzZGljdGkpKSAjIHJlbW92ZSBwb2ludHMgb3V0c2lkZSBzdGF0IHdhdGVycwoKZ2dwbG90KHBvcnRfc2YpICArCiAgZ2VvbV9zZihhZXMoY29sb3IgPSBkaXN0YW5jZV9mcm9tX3Nob3JlX20pKSArCiAgdGhlbWVfZGFyaygpCgpgYGAKU28uLi5Mb29rcyBsaWtlIHNvbWUgcG9ydHMgYXJlICJmYXIgZnJvbSBzaG9yZSIgd2hpY2ggSSBkb24ndCByZWFsbHkga25vdyB3aGF0IGl0IG1lYW5zLiBGb3Igbm93LCBJIGFtIG9ubHkgc2VsZWN0aW5nIHRob3NlIHBvcnRzIHRoYXQgYXIgMCBtZXRlciBmcm9tIHNob3JlLiAKCgpgYGB7ciBwb3J0c19pbnNob3JlLCBldmFsID0gVCwgZWNobyA9IEZ9CgojIEdldCBudW1uZXIgb2YgcG9ydHMgcGVyIHN0YXRlCnBvcnRzX25fZGF0YSA8LSBwb3J0X3NmICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogICAgZmlsdGVyKGRpc3RhbmNlX2Zyb21fc2hvcmVfbSA9PSAwKSAlPiUgCiAgICBncm91cF9ieShzdGF0ZSkgJT4lIAogICAgc3VtbWFyaXNlKG5fcG9ydHMgPSBuKCkpIAoKIyBwbG90IGl0CmdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKAogIHBvcnRfc2YgJT4lIAogICAgZmlsdGVyKGRpc3RhbmNlX2Zyb21fc2hvcmVfbSA9PSAwKSAlPiUgCiAgICBnZ3Bsb3QoKSAgKwogICAgZ2VvbV9zZihhZXMoY29sb3IgPSBqdXJpc2RpY3RpKSkgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogICAgdGhlbWVfZGFyaygpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICIiKSwKICB0YWJsZUdyb2IocG9ydHNfbl9kYXRhKSwKICBuY29sID0gMgopCgoKYGBgCgoKVGhlcmUgYXJlIHN0aWxsIHRvbyBtYW55IHBvcnRzIGluIGVhY2ggc3RhdGUgKD8pLiBTcGVjaWFsbHkgTmV3IEplcnNleSEgT25lIGFwcHJvYWNoIGlzIHRvIHVzZSBOT0FBJ3MgbGFuZGluZy1wZXItcG9ydCBkYXRhIHRvIGZpbHRlciBvdXQuLi4gCgojIyMjIyMgNC4xIE5PQUEncyBkYXRhCgpUaGlzIGRhdGFzZXQgaW5jbHVkZXMgYWxsIGxhbmRpbmdzIGZyb20gMjAxNS1KdWx5IDIwMjEuIEl0IGluY2x1ZGVzIHRoZSBzcGVjaWVzIGxhbmRlZCwgdGhlIHBvcnQsIGFuZCB0aGUgSHVsbCBJRCBhbmQgdmVzc2VsIG5hbWUgZm9yIGJsYWNrIHNlYSBiYXNzIGFuZCBzdW1tZXIgZmxvdW5kZXIuCgoqTGljZW5zZSwgZnJvbSBTYXJhaCBTbWl0aDogVGhpcyBpcyBjb25maWRlbnRpYWwgZGF0YSwgc28gcGxlYXNlIGRvIG5vdCBzaGFyZSB0aGlzIGZpbGUgd2l0aCBvdGhlcnMuIFlvdSBtYXkgbmVlZCB0byBjb250YWN0IE5PQUEgZGlyZWN0bHkganVzdCB0byByZXF1ZXN0IHBlcm1pc3Npb24uIE15IGNvbnRhY3QgaGFzIGJlZW4gQWxpc29uIEZlcmd1c29uIChBbGlzb24uRmVyZ3Vzb25Abm9hYS5nb3YpIGluIHRoZWlyIGRhdGEgZGVwYXJ0bWVudC4qCgpgYGB7cn0KCiMjIyBTUkFIIExBTkRJTkcgREFUQQpyZWFkX2V4Y2VsX2FsbHNoZWV0cyA8LSBmdW5jdGlvbihmaWxlbmFtZSwgdGliYmxlID0gVFJVRSkgewogICAgIyBJIHByZWZlciBzdHJhaWdodCBkYXRhLmZyYW1lcwogICAgIyBidXQgaWYgeW91IGxpa2UgdGlkeXZlcnNlIHRpYmJsZXMgKHRoZSBkZWZhdWx0IHdpdGggcmVhZF9leGNlbCkKICAgICMgdGhlbiBqdXN0IHBhc3MgdGliYmxlID0gVFJVRQogICAgc2hlZXRzIDwtIHJlYWR4bDo6ZXhjZWxfc2hlZXRzKGZpbGVuYW1lKVsyOjhdCiAgICB4IDwtIGxhcHBseShzaGVldHMsIGZ1bmN0aW9uKFgpIHJlYWR4bDo6cmVhZF9leGNlbChmaWxlbmFtZSwgc2hlZXQgPSBYKSkKICAgIGlmKCF0aWJibGUpIHggPC0gbGFwcGx5KHgsIGFzLmRhdGEuZnJhbWUpCiAgICBuYW1lcyh4KSA8LSBzaGVldHMKICAgIHgKfQojIEdldCBkYXRhIHBhdGgKcG9ydHNfcGF0aCA8LSBteV9wYXRoKCJEIiwiTk9BQSIsIG5hbWUgPSAiU1NtaXRoXzIwMTUtMjAyMSBMYW5kaW5nc19KVU4gMjAyMS54bHN4IikKCiMgCnBvcnRzX2RhdGEgPC0gYmluZF9yb3dzKHJlYWRfZXhjZWxfYWxsc2hlZXRzKHBvcnRzX3BhdGgpKSAlPiUKICBjbGVhbl9uYW1lcygpICU+JQogIG11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsCiAgICAgICAgICAgICAgfiBzdHJfdG9fbG93ZXIoLikpICU+JSAKICBtdXRhdGUobGFuZGluZ19wb3J0ID0gc3RyX3JlbW92ZShsYW5kaW5nX3BvcnQsIls6Ymxhbms6XVxcKHN0YXRlXFwpIikpCgpub2FhX3BvcnRzIDwtIHVuaXF1ZShwb3J0c19kYXRhJGxhbmRpbmdfcG9ydCkKCm5vYWFfcG9ydCA8LSBwb3J0X3NmICU+JSAKICBmaWx0ZXIoZGlzdGFuY2VfZnJvbV9zaG9yZV9tID09IDApICU+JSAKICBtdXRhdGUobGFiZWwgPSBzdHJfdG9fbG93ZXIobGFiZWwpKSAlPiUgCiAgZmlsdGVyKGxhYmVsICVpbiUgbm9hYV9wb3J0cykKCiMgR2V0IG51bWJlciBvZiBwb3J0cyBwZXIgc3RhdGUKbm9hYV9wb3J0c19uX2RhdGEgPC0gbm9hYV9wb3J0ICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogICAgZ3JvdXBfYnkoc3RhdGUpICU+JSAKICAgIHN1bW1hcmlzZShub2FhX3BvcnRzID0gbigpKSAKCiMgR2V0IG51bWJlciBvZiBwb3J0cyBpbiB0aGUgTk9BQSBkYXRhYmFzZQoKbl9wb3J0c19kYXRhIDwtIHBvcnRzX2RhdGEgJT4lIAogIGdyb3VwX2J5KGxhbmRpbmdfc3RhdGUpICU+JSAKICBzdW1tYXJpc2Uobm9hYV9wb3J0cyA9IGxlbmd0aCh1bmlxdWUobGFuZGluZ19wb3J0KSkpICU+JSAKICBtdXRhdGUoYWJyZXYgPSBzdHJfdG9fdXBwZXIobGFuZGluZ19zdGF0ZSkpICU+JSAKICBsZWZ0X2pvaW4obGFuZF9zZikgJT4lIAogIHNlbGVjdChzdGF0ZSxub2FhX3BvcnRzKSAlPiUgCiAgZmlsdGVyKCFpcy5uYShzdGF0ZSkpICU+JSAKICBsZWZ0X2pvaW4obm9hYV9wb3J0c19uX2RhdGEpCgojIHBsb3QgaXQKZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UoCiAgcG9ydF9zZiAlPiUgCiAgICBtdXRhdGUobGFiZWwgPSBzdHJfdG9fbG93ZXIobGFiZWwpKSAlPiUgCiAgICBmaWx0ZXIoZGlzdGFuY2VfZnJvbV9zaG9yZV9tID09IDAsCiAgICAgICAgICAgbGFiZWwgJWluJSBub2FhX3BvcnRzCiAgICAgICAgICAgKSAlPiUgCiAgICBnZ3Bsb3QoKSAgKwogICAgZ2VvbV9zZihhZXMoY29sb3IgPSBqdXJpc2RpY3RpKSkgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogICAgdGhlbWVfZGFyaygpLAogICAgIyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiIiksCiAgdGFibGVHcm9iKG5fcG9ydHNfZGF0YSksCiAgbmNvbCA9IDIKKQogIApgYGAKCgpUaGlzIGFwcHJvYWNoIHJlbW92ZXMgYSBsb3Qgb2YgcG9ydHMgdG8gdGhlIHBvaW50IHRoYXQgRGVsYXdhcmUgaXMgY29tcGxldGVseSBwb3J0LWxlc3MKCiMjIyMjIyA0LjIgV29ybGQgUG9ydCBJbmRleCAKCkluIHRoaXMgYXBwcm9hY2ggd2Ugb25seSB1c2UgdGhlIHBvcnRzIGNhdGVnb3JpemVkIHdpdGhpbiB0aGUgW1dQSV0oaHR0cHM6Ly9tc2kubmdhLm1pbC9OR0FQb3J0YWwvTVNJLnBvcnRhbD9fbmZwYj10cnVlJl9wYWdlTGFiZWw9bXNpX3BvcnRhbF9wYWdlXzYyJnB1YkNvZGU9MDAxNSkgYW5kIHdpdGggYGRpc3RhbmNlX2Zyb21fc2hvcmVfbSA9PSAwYCAgYW5kIGBhdF9kb2NrID09IFRSVUVgLgoKLSBgYXRfZG9ja2AgPT0gQW5jaG9yYWdlcyB3aXRoaW4gYSA0NTAgbWV0ZXIgYnVmZmVyIGFyb3VuZCBhIGNvbWJpbmVkIGxhbmQgc2hhcGUgZmlsZSBhcmUgY29uc2lkZXJlZCBhdCBkb2NrLiAKCmBgYHtyIHdwaV9hcHByb2FjaCwgZXZhbCA9IFQsIGVjaG8gPSBGfQoKZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UoCiAgcG9ydF9zZiAlPiUgCiAgICBmaWx0ZXIoZGlzdGFuY2VfZnJvbV9zaG9yZV9tID09IDAsCiAgICAgICAgICAgbGFiZWxfc291cmNlICVpbiUgYygiV1BJX3BvcnRzIiksCiAgICAgICAgICAgYXRfZG9jayA9PSBUUlVFKSAlPiUgCiAgICBnZ3Bsb3QoKSAgKwogICAgZ2VvbV9zZihhZXMoY29sb3IgPSBqdXJpc2RpY3RpKSkgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogICAgdGhlbWVfZGFyaygpLAogIHBvcnRfc2YgJT4lIAogICAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICAgIGZpbHRlcihkaXN0YW5jZV9mcm9tX3Nob3JlX20gPT0gMCwKICAgICAgICAgICBsYWJlbF9zb3VyY2UgJWluJSBjKCJXUElfcG9ydHMiKSwKICAgICAgICAgICBhdF9kb2NrID09IFRSVUUpICU+JSAKICAgIGdyb3VwX2J5KHN0YXRlKSAlPiUgCiAgICBzdW1tYXJpc2Uobl9wb3J0cyA9IG4oKSkgJT4lIAogICAgdGFibGVHcm9iKCksCiAgbmNvbCA9IDIKKQoKCmBgYAoKVGhpcyBhcHByb2FjaCBtaWdodCBiZSBiZXR0ZXIgc3VpdGVkLiBJdCBhbHNvIGhhcyB0ZWggYWR2YW50YWdlIHRoYXQgd2UgYXJlIHVzaW5nIHRoZSBXUEkuCgpUaGlzIGlzIGhvdyBhbGwgdGhlIHNoYXBlZmlsZXMgbG9vayBsaWtlIHRvZ2V0aGVyCgoKYGBge3IgYWxsX3NmLCBldmFsID0gVCwgZWNobyA9IFR9Cgpwb3J0X3NmIDwtIHBvcnRfc2YgJT4lIAogICAgZmlsdGVyKGRpc3RhbmNlX2Zyb21fc2hvcmVfbSA9PSAwLAogICAgICAgICAgIGxhYmVsX3NvdXJjZSAlaW4lIGMoIldQSV9wb3J0cyIpLAogICAgICAgICAgIGF0X2RvY2sgPT0gVFJVRSkKCiMgVmlzdWFsIGV4cGxvcmF0aW9uIG9mIGFsbCB0b2dldGhlciAoby5rISApCmdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsIGFlcygpKSArCiAgZ2VvbV9zZihkYXRhID0gbGFuZF9zZiwgYWVzKGZpbGwgPSBzdGF0ZSksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zZihkYXRhID0gc3RhdGVfc2YsIGFlcyhjb2xvciA9IHN0YXRlKSwgZmlsbCA9IE5BKSArCiAgZ2VvbV9zZihkYXRhID0gcG9ydF9zZiwgYWVzKGNvbG9yID0gc3RhdGUpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogIHRoZW1lX2RhcmsoKSArCiAgY29vcmRfc2YoeWxpbSA9IGMoMzMsNDgpKQoKYGBgCgoKIyMjIENyZWF0ZSBiYXNlIHNoYXBlZmlsZSBmb3IgY29tcHV0YXRpb24KCkFzIGEgZmlyc3Qgc3RlcCB3ZSBuZWVkIHRvIGRpdmlkZSB0aGUgTkUgVVMgRUVaIGFtb25nIHRoZSBkaWZmZXJlbnQgc3RhdGVzLiBGb3IgdGhhdCwgd2UgZXhwYW5kZWQgYSBidWZmZXItcG9seWdvbiB0byB0aGUgMjAwIG5hdXRpY2FsIG1pbGVzIHRvIHRoZW4gZXN0aW1hdGUgdGhlIHBlcmNlbnRhZ2UgdGhhdCBlYWNoIGV4cGFuZGVkIHBvbHlnb24gb2NjdXBpZWQuIEZvciB0aGUgaW5pdGlhbCBidWZmZXIgcG9pbnQgd2UgdXNlZCB0d28gYXBwcm9hY2hlczsgc3RhdGUgd2F0ZXJzIGFuZCBVUyBwb3J0cy4gTm90ZSB0aGF0IGluIGFsbCBjYXNlcyB0aGVzZSBhcmVhcyBvdmVybGFwcGVkIGFuZCBwZXJjZW50YWdlcyBhY2NvdW50ZWQgZm9yIGl0LiBXZSBkaWQgdGhpcyBieSBmb2xsb3dpbmcgdGhlc2Ugc3RlcHM6CgotIDEuIEV4cGFuZCBzdGF0ZSB3YXRlcnMgLyBVUyBwb3J0cyB1c2luZyBhIGJ1ZmZlcgoKLSAyLiBHcmlkIHRoYXQgYnVmZmVyIG9uIGEgMC4zIHJlc29sdXRpb24KCi0gMy4gQ3JvcCB0aGUgYnVmZmVyIHRvIHRoZSBFRVoKCiMjIyMgMS4gRXhwYW5kIFNwYXRpYWwgcmVnaW9ucyAoYS5rLmEgIGJ1ZmZlcnMpCgojIyMjIyAxLjEgU3RhdGUgV2F0ZXJzCgpXZSBzZXQgYSBidWZmZXIgb2YgKjQxMDAwMCogbSAoNDEwIGttLCB+IDIyMSBubSkgdGhhdCBvdmVyc2hvb3RzIHRoZSBFRVogYSBiaXQsIGJ1dCBpcyBldmVudHVhbGx5IGNyb3BwZWQKCmBgYHtyIHN3X2J1ZmZlciwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKIyBCdWZmZXIgc3RhdGUgd2F0ZXJzCnN0YXRlX2JmID0gc3RfYnVmZmVyKHN0YXRlX3NmLCA0KSAlPiUgCiAgc3RfdHJhbnNmb3JtKDQzMjYpICU+JSAjIHRvIG1hdGNoIHNoYXBlCiAgc3Rfc2V0X2Nycyg0MzI2KQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwojIFRlc3RpbmcgYW5kIHZpc3VhbGl6aW5nIHRoZSBidWZmZXIgCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCnN0YXRlX2JmX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YSA9IHN0YXRlX3NmLCBhZXMoY29sb3IgPSBzdGF0ZSksIGZpbGwgPSBOQSkgKwogIGdlb21fc2YoZGF0YSA9IGVlel9zZiwgYWVzKCksIGZpbGwgPSBOQSkgKwogIGdlb21fc2YoZGF0YSA9IHN0YXRlX2JmLCBhZXMoY29sb3IgPSBzdGF0ZSksIGZpbGwgPSBOQSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpKwogIHRoZW1lX2RhcmsoKQojICAgCgojIGdnc2F2ZSgiLi4vUmVzdWx0cy9QYXJ0aWFsL3N0YXRlX3dhdGVyc19idWZmZXIucG5nIixzdGF0ZV9iZl9wbG90KQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKc3RhdGVfYmZfcGxvdAoKYGBgCgojIyMjIyAxLjEgVVMuIFBvcnRzCgpXZSBzZXQgYSBidWZmZXIgb2YgKjUqIGRlZyAoNTEwIGttLCB+IDIyMSBubSkgdGhhdCBvdmVyc2hvb3RzIHRoZSBFRVogYSBiaXQsIGJ1dCBpcyBldmVudHVhbGx5IGNyb3BwZWQKCmBgYHtyIGZwX2J1ZmZlciwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKIyBCdWZmZXIgc3RhdGUgd2F0ZXJzCnBvcnRfYmYgPSBzdF9idWZmZXIocG9ydF9zZiwgNSkgJT4lICMgcG9ydAogIHN0X3RyYW5zZm9ybSg0MzI2KSAlPiUgIyB0byBtYXRjaCBzaGFwZQogIHN0X3NldF9jcnMoNDMyNikKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKIyBUZXN0aW5nIGFuZCB2aXN1YWxpemluZyB0aGUgYnVmZmVyIAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgpnZ3Bsb3QoKSArCiAgZ2VvbV9zZihkYXRhID0gZWV6X3NmLCBhZXMoKSxmaWxsID0gTkEpICsKICBnZW9tX3NmKGRhdGEgPSBwb3J0X2JmLCBhZXMoY29sb3IgPSBzdGF0ZSksIGZpbGwgPSBOQSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpKwogIHRoZW1lX2RhcmsoKQoKYGBgCgoKIyMjIyAyLiBFeHBhbmQgZ3JpZCB3aXRoaW4gYnVmZmVyCgpIZXJlIHdlIGV4cGFuZCBhIGdyaWQgd2l0aGluIHRoZSBidWZmZXIgc28gd2UgY2FuIGVzdGltYXRlIHRoZSBwcm9wb3J0aW9uIG9mIGVhY2ggc3RhdGUuCgoqTm90ZToqIERhcmsgZ3JleSBzaGFkZWQgYXJlYSBpcyB0aGUgZ3JpZCBhbmQgaXMgdGhlIHNhbWUgZm9yIGJvdGggYXBwcm9hY2hlcwoKYGBge3IgZ3JpZF9pbmRleGluZywgZXZhbCA9IFQsIGVjaG8gPSBULCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEZ9CgojIENyZWF0ZSBncmlkIG9mIHRoZSByZWdpb24KYmJveCA8LSBjKHN0X2Jib3goc3RhdGVfYmYpKQoKIyBFeHBhbmQgdGhlIGdyaWQKbmVfZ3JpZCA8LSBleHBhbmQuZ3JpZCgKICAgIGxvbiA9IHNlcShmcm9tID0gYmJveFsieG1pbiJdLCB0byA9IGJib3hbInhtYXgiXSwgYnkgPSAwLjMpLAogICAgbGF0ID0gc2VxKGZyb20gPSBiYm94WyJ5bWluIl0sIHRvID0gYmJveFsieW1heCJdLCBieSA9IDAuMykKKSAlPiUgCiAgcm93aWRfdG9fY29sdW1uKCJpbmRleCIpCgojIC0tLS0tLS0tLS0tICMKIyBbVEVTVF0gUGxvdCBhbGwgbGF5ZXJzCiMgLS0tLS0tLS0tLS0gIwoKIyBMb29rcyBnb29kCnN0YXRlX3NmICU+JQogIHN0X3RyYW5zZm9ybSg0MzI2KSAlPiUgIyB0byBtYXRjaCBzaGFwZQogIHN0X3NldF9jcnMoNDMyNikgJT4lCiAgIyBzdF9zaW1wbGlmeShwcmVzZXJ2ZVRvcG9sb2d5ID0gVFJVRSwgZFRvbGVyYW5jZSA9IDEwMDAwKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoY29sb3IgPSBzdGF0ZSkpKwogICMgZ2VvbV9zZihkYXRhID0gZWV6X3NmLCBhZXMoKSxmaWxsID1OQSkgKwogICMgZ2dwbG90KCkrCiAgZ2VvbV90aWxlKGRhdGEgPSBuZV9ncmlkLAogICAgICAgICAgICBhZXMoCiAgICAgICAgICAgICAgeCA9IGxvbiwKICAgICAgICAgICAgICB5ID0gbGF0CiAgICAgICAgICAgICksCiAgICAgICAgICAgIGFscGhhID0gMC4yCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lX2RhcmsoKQoKCmBgYAoKIyMjIyMgMi4xIE1lcmdlIGdyaWQgYW5kIGJ1ZmZlcnMKCk9uY2Ugd2UgaGF2ZSBhIGdyaWRkZWQgYXJlYSwgd2UgY29udmVydGVkIHRoZSBncmlkIHRvIGEgYHNmYCBzbyB3ZSBjYW4gbWVyZ2UgaXQgd2l0aCB0aGUgYnVmZmVyZWQgc3RhdGVzIGFuZCBwb3J0cyBhbmQgZmluYWxseSBmaWx0ZXIgb3V0IGV2ZXJ5dGhpbmcgb3V0c2lkZSB0aGUgc3RhdGVzIHBvbHlnb24KCiMjIyMjIyAyLjEuMSBTdGF0ZSBXYXRlcnMKCmBgYHtyIGdyaWRfc3dfYnVmX21lcmdlLCBldmFsID0gVCwgZWNobyA9IFQsIG1lc3NhZ2UgPSBGLCB3YXJuaW5nID0gRiwgZmlnLndpZHRoID0gMTB9CgojIC0tLS0tLS0tLS0tLS0tLS0gIwojIENvbnZlcnQgZ3JpZCB0byBzZgojIC0tLS0tLS0tLS0tLS0tLS0gIwpncmlkX3N3X3NmIDwtIHN0X2FzX3NmKG5lX2dyaWQsCiAgICAgICAgICAgICBjb29yZHMgPSBjKCJsb24iLCAibGF0IiksCiAgICAgICAgICAgICBjcnMgPSA0MzI2KSAlPiUgCiAgc3Rfam9pbihzdGF0ZV9iZikgJT4lIAogIGZpbHRlcighaXMubmEoc3RhdGUpKQoKIyBDcmVhdGUgZGF0YSBmcmFtZSBmb3IgZnV0dXJlIGNvbXB1dGF0aW9ucwojIE5vdGUsIHdpbGwgYmUgdXNlZCBpbiBuZXh0IGNodW5rCmdyaWRfc3dfYmZfZHQgPC0gYXMuZGF0YS5mcmFtZShncmlkX3N3X3NmKSAlPiUKICAgIHNlbGVjdChpbmRleCxzdGF0ZSkKICAgICMgZ3JvdXBfYnkoc3RhdGUpICU+JSAKICAgICMgc3VtbWFyaXNlKGxlbmd0aChpbmRleCkpCgoKIyAtLS0tLS0tLS0tLS0tLS0tICMKIyBbVEVTVF0gCiMgVmlzdWFsaXphdGlvbiBvZiBncmlkCiMgLS0tLS0tLS0tLS0tLS0tLSAjCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZSgKICAjIE92ZXJhbGwgKG92ZXJsYXBwaW5nKSBwb3NpdGlvbgogIGdncGxvdChncmlkX3N3X3NmKSArCiAgICBnZW9tX3NmKGRhdGEgPSBzdGF0ZV9zZiwgYWVzKCksIGZpbGwgPSBOQSkgKwogICAgZ2VvbV9zZihhZXMoY29sb3IgPSBzdGF0ZSksIGFscGhhID0gMC4zKSArCiAgICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsIGFlcygpLGZpbGwgPU5BKSArIAogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogICAgdGhlbWVfZGFyaygpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICIiKSwKICAjIFNob3dpbmcgZWFjaCBzdGF0ZSBzZXBhcmF0bGV5CiAgZ2dwbG90KCkgKwogICAgZ2VvbV9zZihkYXRhID0gZ3JpZF9zd19zZiwgYWVzKGNvbG9yID0gc3RhdGUpLHNpemUgPSAwLjEsIGFscGhhID0gMC41KSArCiAgICBmYWNldF93cmFwKH5zdGF0ZSkgKwogICAgdGhlbWVfZGFyaygpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSwKICBucm93ID0gMSkgCgpgYGAKCiMjIyMjIyAyLjEuMSBGaXNoaW5nIFBvcnRzCgpgYGB7ciBncmlkX2ZwX2J1Zl9tZXJnZSwgZXZhbCA9IFQsIGVjaG8gPSBULCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEYsIGZpZy53aWR0aCA9IDEwfQoKIyAtLS0tLS0tLS0tLS0tLS0tICMKIyBDb252ZXJ0IGdyaWQgdG8gc2YKIyAtLS0tLS0tLS0tLS0tLS0tICMKZ3JpZF9mcF9zZiA8LSBzdF9hc19zZihuZV9ncmlkLAogICAgICAgICAgICAgY29vcmRzID0gYygibG9uIiwgImxhdCIpLAogICAgICAgICAgICAgY3JzID0gNDMyNikgJT4lIAogIHN0X2pvaW4ocG9ydF9iZikgJT4lICMgam9pbiB0byBwb3J0IHNmCiAgZmlsdGVyKCFpcy5uYShzdGF0ZSkpICU+JSAKICBkaXN0aW5jdChpbmRleCxzdGF0ZSwgLmtlZXBfYWxsID0gVFJVRSkgI3JlbW92ZXMgbGlrZSA0MDBLIG92ZXJsYXBwaW5nIHJvd3MKCiMgQ3JlYXRlIGRhdGEgZnJhbWUgZm9yIGZ1dHVyZSBjb21wdXRhdGlvbnMKIyBOb3RlLCB3aWxsIGJlIHVzZWQgaW4gbmV4dCBjaHVuawpncmlkX2ZwX2JmX2R0IDwtIGFzLmRhdGEuZnJhbWUoZ3JpZF9mcF9zZikgJT4lCiAgICBzZWxlY3QoaW5kZXgsc3RhdGUpCgojIC0tLS0tLS0tLS0tLS0tLS0gIwojIFtURVNUXSAKIyBWaXN1YWxpemF0aW9uIG9mIGdyaWQKIyAtLS0tLS0tLS0tLS0tLS0tICMKCmdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKAogICMgT3ZlcmFsbCAob3ZlcmxhcHBpbmcpIHBvc2l0aW9uCiAgZ2dwbG90KGdyaWRfZnBfc2YpICsKICAgIGdlb21fc2YoZGF0YSA9IHBvcnRfc2YsIGFlcygpLCBmaWxsID0gTkEpICsKICAgIGdlb21fc2YoYWVzKGNvbG9yID0gc3RhdGUpLCBhbHBoYSA9IDAuMykgKwogICAgZ2VvbV9zZihkYXRhID0gZWV6X3NmLCBhZXMoKSxmaWxsID1OQSkgKyAKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpICsKICAgIHRoZW1lX2RhcmsoKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiIiksCiAgIyBTaG93aW5nIGVhY2ggc3RhdGUgc2VwYXJhdGVseQogIGdncGxvdCgpICsKICAgIGdlb21fc2YoZGF0YSA9IGdyaWRfZnBfc2YsIGFlcyhjb2xvciA9IHN0YXRlKSxzaXplID0gMC4xLCBhbHBoYSA9IDAuNSkgKwogICAgZmFjZXRfd3JhcCh+c3RhdGUpICsKICAgIHRoZW1lX2RhcmsoKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCksCiAgbnJvdyA9IDEpCgpgYGAKCiMjIyMgMy4gQ3JvcCBidWZmZXJzIHRvIEVFWgoKRmluYWxseSwgd2UgY3JvcCB0aGUgZ3JpZGVkIGJ1ZmZlcnMgdG8gd2l0aGluIHRoZSBFRVogdG8gY2FwdHVyZSB0aGUgYWN0dWFsIHdhdGVyIHNwYWNlLgoKKk5vdGU6KiBUaGlzIHN0ZXAgdGFrZXMgcXVpdGUgYSB3aGlsZSBiZWNhdXNlIG9mIHRoZSBzaXplIG9mIHRoZSBFRVogc2hhcGVmaWxlLiBObywgeW91IGNhbm5vdCB1c2UgYHN0X3NpbXBsaWZ5KClgIGhlcmUKCiMjIyMgMy4xIFN0YXRlIFdhdGVycwoKYGBge3IgYnVmZl9zd190b19lZXosIGV2YWwgPVQsIGVjaG8gPSBULCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEZ9CgojIEkgZG9uJ3Qga25vdyBob3cgdG8gdW5kbyBzdF9zaW1wbGlmeSBzbyBuZWVkIHRvIHJlLWxvYWQgdGhlIHNoYXBlZmlsZQoKZWV6X3NmIDwtIHN0X3JlYWQobXlfcGF0aCgiRyIsIGV4dHJhX3BhdGggPSAiU3BhdGlhbC9TQVUvU0FVX1NoYXBlZmlsZSIsIG5hbWUgPSAiU0FVRUVaX0p1bHkyMDE1LnNocCIpKSAlPiUgCiAgcmVuYW1lKGVlel9uYW1lID0gTmFtZSkgJT4lIAogIHN0X3RyYW5zZm9ybShjcnMgPSA0MzI2KSAlPiUgIyA0MzI2CiAgZmlsdGVyKGVlel9uYW1lID09ICJVU0EgKEVhc3QgQ29hc3QpIikgCgojIEdldCB0aGUgb3ZlcmxhcHBpbmcgc2VnbWVudHMgCiMgTk9URTogVGFrZXMgc29tZSBnb29vb29vZCB0aW1lICh+MjAgbWluKQpTeXMudGltZSgpCmdyaWRfZWV6X3NmX3N3IDwtIHN0X2ludGVyc2VjdGlvbihncmlkX3N3X3NmLGVlel9zZikKU3lzLnRpbWUoKQojIHdyaXRlX3NmKGdyaWRfZWV6X3NmLCBwYXN0ZTAobXlfcGF0aCgiRCIsICJTcGF0aWFsIiksImdyaWRfZWV6X3NmLnNocCIpKQoKIyBHZXQgZmluYWwgZGYgd2l0aCBpbmRleApncmlkX2Vlel9zd19kZiA8LSBhcy5kYXRhLmZyYW1lKGdyaWRfZWV6X3NmX3N3KSAlPiUKICBzZWxlY3Qoc3RhdGUsaW5kZXgpICU+JQogIGxlZnRfam9pbihuZV9ncmlkLAogICAgICAgICAgICBieSA9ICJpbmRleCIpCgojIHdyaXRlX2NzdihncmlkX2Vlel9kZiwgcGFzdGUwKG15X3BhdGgoIlIiLCAiUGFydGlhbCIpLCJncmlkX2Vlel9kZi5jc3YiKSkKCiMgUGxvdCB0byBtYWtlIHN1cmUgbWFrZXMgc2Vuc2UKCmVlel9zZiA8LSBlZXpfc2YgJT4lIAogIHN0X3NpbXBsaWZ5KHByZXNlcnZlVG9wb2xvZ3kgPSBUUlVFLCBkVG9sZXJhbmNlID0gMC4xKSAjMC4xIGZvciBwYXBlcgoKZ3JpZF9lZXpfc2Zfc3cgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoYWVzKGNvbG9yID0gc3RhdGUpLCBhbHBoYSA9IDAuMykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpICsKICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsYWVzKCksIGZpbGwgPSBOQSkgKwogIHRoZW1lX2RhcmsoKQoKYGBgCgoKIyMjIyAzLjIgRmlzaGluZyBQb3J0cwoKYGBge3IgYnVmZl9mcF90b19lZXosIGV2YWwgPVQsIGVjaG8gPSBULCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEZ9CgojIEdldCB0aGUgb3ZlcmxhcHBpbmcgc2VnbWVudHMgCiMgTk9URTogVGFrZXMgc29tZSBnb29vb29vZCB0aW1lICh+MjAgbWluKQpTeXMudGltZSgpCmdyaWRfZWV6X2ZwX3N3IDwtIHN0X2ludGVyc2VjdGlvbihncmlkX2ZwX3NmLGVlel9zZikKU3lzLnRpbWUoKQojIHdyaXRlX3NmKGdyaWRfZWV6X3NmLCBwYXN0ZTAobXlfcGF0aCgiRCIsICJTcGF0aWFsIiksImdyaWRfZWV6X3NmLnNocCIpKQoKIyBHZXQgZmluYWwgZGYgd2l0aCBpbmRleApncmlkX2Vlel9mcF9kZiA8LSBhcy5kYXRhLmZyYW1lKGdyaWRfZWV6X2ZwX3N3KSAlPiUKICBzZWxlY3Qoc3RhdGUsaW5kZXgpICU+JQogIGxlZnRfam9pbihuZV9ncmlkLAogICAgICAgICAgICBieSA9ICJpbmRleCIpCgojIHdyaXRlX2NzdihncmlkX2Vlel9kZiwgcGFzdGUwKG15X3BhdGgoIlIiLCAiUGFydGlhbCIpLCJncmlkX2Vlel9kZi5jc3YiKSkKCiMgUGxvdCB0byBtYWtlIHN1cmUgbWFrZXMgc2Vuc2UKZ3JpZF9lZXpfZnBfc3cgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoYWVzKGNvbG9yID0gc3RhdGUpLCBhbHBoYSA9IDAuMykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpICsKICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsYWVzKCksIGZpbGwgPSBOQSkgKwogIHRoZW1lX2RhcmsoKQoKYGBgCgojIyMjIDMuMyBEaWZmZXJlbmNlcyBhdCBjcm9wZWRlIGxldmVsCgpCeSBsb29raW5nIGF0IHRoZSBwbG90cyB3ZSBkbyBub3Qgc2VlIHRoYXQgdGhlIG51bWJlciBvZiBncmlkIGNlbGxzIHRoYXQgZWFjaCBzdGF0ZSBoYXMgaXMgc2xpZ2h0bHkgZGlmZmVyZW50IGRlcGVuZGluZyBvbiB0aGUgYXBwcm9hY2guIFRoaXMgY29tZXMgdG8gbGlnaHQgd2hlbiB3ZSBjb3VudCB0aGUgbnVtYmVyIG9mIGdyaWRjZWxscyB0aGF0IGVhY2ggc3RhdGUgZ2V0cyBpbiBlYWNoIGFwcHJvYWNoLiBXZSBzZWUgdGhhdCB0aGUgc3RhdGUgd2F0ZXJzIG9uZSBpcyBzdWJzdGFudGlhbGx5IGhpZ2hlci4KCldlIGNhbiB2aXN1YWxpemUgdGhlIGRpZmZlcmVuY2Ugb2YgdGhlIGNyb3BwZWQgYXJlYSBmb3IgZWFjaCBzdGF0ZSBuZXh0LiBBZ2FpbiwgdGhlIGZpc2hpbmcgcG9ydCBhcHByb2FjaCByZXN1bHRzIGluIGxlc3MgYXJlYSBmb3IgYWxsIHN0YXRlcywgYnV0IHN1Y2ggYXJlYSBpcyBub3QgcHJvcG9ydGlvbmFsIGFtb25nIHN0YXRlcy4gRm9yIGV4YW1wbGUsIERlbGF3YXJlIGxvb3NlcyByb3VnaGx5IDM1JSBvZiBmaXNoaW5nIGdyb3VuZHMgd2l0aCB0aGlzIGFwcHJvYWNoCgpgYGB7ciBzdGF0ZV9iZl9kaWZmX3RibCwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKZ3JpZF9lZXpfc3dfZGYgJT4lIAogIG11dGF0ZShhcHByb2FjaCA9ICJzdGF0ZV93YXRlcnMiKSAlPiUgCiAgYmluZF9yb3dzKGdyaWRfZWV6X2ZwX2RmKSAlPiUKICBtdXRhdGUoYXBwcm9hY2ggPSBpZmVsc2UoaXMubmEoYXBwcm9hY2gpLCJmaXNoaW5nX3BvcnQiLGFwcHJvYWNoKSkgJT4lIAogIGdyb3VwX2J5KHN0YXRlLGFwcHJvYWNoKSAlPiUgCiAgc3VtbWFyaXNlKG5fZ3JpZCA9IG4oKSkgJT4lIAogIHNwcmVhZChhcHByb2FjaCxuX2dyaWQpICU+JSAKICBtdXRhdGUoZGlmZmVyZW5jZSA9c3RhdGVfd2F0ZXJzLWZpc2hpbmdfcG9ydCwKICAgICAgICAgcGVyY2VudGFnZV9zdyA9IHJvdW5kKChkaWZmZXJlbmNlL3N0YXRlX3dhdGVycykqMTAwKQogICAgICAgICApCgpgYGAKCkFuZCBoZXJlIGlzIHRoZSBtYXAgdmlzdWFsaXphdGlvbiBvZiB0aGUgY3JvcHBlZCBkaWZmZXJlbmNlCgpgYGB7ciBzdGF0ZV9iZl9kaWZmX21hcCwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKZ3JpZF9lZXpfc3dfZGYgJT4lIAogIG11dGF0ZShhcHByb2FjaCA9ICJzdGF0ZV93YXRlcnMiKSAlPiUgCiAgYmluZF9yb3dzKGdyaWRfZWV6X2ZwX2RmKSAlPiUKICBtdXRhdGUoYXBwcm9hY2ggPSBpZmVsc2UoaXMubmEoYXBwcm9hY2gpLCJmaXNoaW5nX3BvcnQiLGFwcHJvYWNoKSkgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX3RpbGUoCiAgICBhZXMoCiAgICAgIHggPSBsb24sCiAgICAgIHkgPSBsYXQsCiAgICAgIGNvbG9yID0gYXBwcm9hY2gsCiAgICAgIGZpbGwgPSBhcHByb2FjaAogICAgKQogICkgKwogIGZhY2V0X3dyYXAofnN0YXRlKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArCiAgdGhlbWVfZGFyaygpCgpgYGAKCiMjIyMjIDMuMSBQYXBlciBmaWd1cmU7IGJ1ZmZlciBwbG90CgpgYGB7ciBjcm9wcGVkX3Bsb3RfcGFwZXIsIGV2YWwgPSBGLCBlY2hvID0gVH0KCgpwbG90X2RhdGEgPC1ncmlkX2Vlel9zZiAlPiUgCiAgICBtdXRhdGUoc3RhdGUgPSBzdHJfdG9fc2VudGVuY2Uoc3RhdGUpKSAlPiUgCiAgICBsZWZ0X2pvaW4oc3RhdGVfbGF0KQoKcCA8LSBncmlkRXh0cmE6OmdyaWQuYXJyYW5nZSgKICAjIE92ZXJhbGwgKG92ZXJsYXBwaW5nKSBwb3NpdGlvbgogIGdncGxvdChwbG90X2RhdGEpICsKICAgIGdlb21fc2YoZGF0YSA9IGVlel9zZiwgYWVzKCksIGZpbGwgPSAid2hpdGUiKSArIAogICAgZ2VvbV9zZihhZXMoY29sb3IgPSBvcmRlciwgZmlsbCA9IG9yZGVyKSwgYWxwaGEgPSAwLjMpICsKICAgIGdlb21fc2YoZGF0YSA9IGxhbmRfc2YsIGFlcygpKSArCiAgICBnZW9tX3NmX2xhYmVsX3JlcGVsKGRhdGEgPSBsYW5kX3NmLCBhZXMobGFiZWw9IGFicmV2KSwgCiAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMiwKICAgICAgICAgICAgICAgICAgICAgIGJveC5wYWRkaW5nID0gMC4xMCwKICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgICBteV9nZ3RoZW1lX3AobGVnX3BvcyA9ICIiLAogICAgICAgICAgICAgICAgIGF4X3R4X3MgPSAxMikgKwogICAgY29vcmRfc2YoeWxpbSA9IGMoMzAsNDgpKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygzMCwzNSw0MCw0NSkpKwogICAgbGFicyh4ID0gIiIsIHkgPSAiIiksCiAgIyBTaG93aW5nIGVhY2ggc3RhdGUgc2VwYXJhdGVseQogIAogICAgZ2dwbG90KHBsb3RfZGF0YSkgKwogICAgZ2VvbV9zZihkYXRhID0gbGFuZF9zZiwgYWVzKCksIGZpbGwgPSAiZ3JleTgwIikgKwogICAgZ2VvbV9zZiggYWVzKGNvbG9yID0gb3JkZXIpLHNpemUgPSAwLjEsIGFscGhhID0gMC44KSArCiAgICBmYWNldF93cmFwKH4gc3RhdGUpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0LAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHBsb3RfZGF0YSAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkpICsKICAgIG15X2dndGhlbWVfcChsZWdfcG9zID0gIiIsCiAgICAgICAgICAgICAgICAgYXhfdHhfcyA9IDYsCiAgICAgICAgICAgICAgICAgYXh4X3R4X2FuZyA9IDQ1LAogICAgICAgICAgICAgICAgIGhqdXN0ID0gMQogICAgICAgICAgICAgICAgICksCiAgbnJvdyA9IDEsCiAgYm90dG9tID0gIkxvbmdpdHVkZSIsCiAgbGVmdCA9ICJMYXRpdHVkZSIpCgoKICBnZ3NhdmUoZmlsZW5hbWUgPSAiYnVmZmVyX2ZpZ3VyZS5qcGciLAogICAgICAgICBwbG90ID0gcCwKICAgICAgICAgcGF0aCA9IG15X3BhdGgoIlIiLCJGaWd1cmVzIiksCiAgICAgICAgIHdpZHRoID0gMTAsCiAgICAgICAgIGhlaWdodCA9IDUKICAgICAgICAgKQoKYGBgCgohW0J1ZmZlciBmaWd1cmUgZm9yIHBhcGVyXSgvVm9sdW1lcy9FbnRlcnByaXNlL0RhdGEvQWNyb3NzQm91bmRhcmllcy9SZXN1bHRzL0ZpZ3VyZXMvYnVmZmVyX2ZpZ3VyZS5qcGcpCgoKCgpgYGB7ciByZW1vdmVfcGVuLCBldmFsID0gRiwgZWNobyA9IEZ9CgojIyMjX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18jIyMgCiMgU29sdmluZyBmb3IgSXNzdWUgIzggUGVubnN5bHZhbmlhIGhhcyBOTyBjb2FzdAojIyMjX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18jIyMgCgojIFJlbW92ZSBQZW5uc3lsdmFuaWEgZnJvbSBzZgpncmlkX2Vlel9zZiA8LSAgc3RfcmVhZCgiL1ZvbHVtZXMvRW50ZXJwcmlzZS9EYXRhL0Fjcm9zc0JvdW5kYXJpZXMvRGF0YS9TcGF0aWFsL2dyaWRfc2YvZ3JpZF9lZXpfc2Yuc2hwIikgJT4lCiAgZmlsdGVyKHN0YXRlICE9ICJwZW5uc3lsdmFuaWEiKQoKIyBNYWtlIHN1cmUgbm8gUGVubi4KdW5pcXVlKGdyaWRfZWV6X3NmJHN0YXRlKQoKIyBvdmVyIHdyaXRlIHNmCndyaXRlX3NmKGdyaWRfZWV6X3NmLCBwYXN0ZTAobXlfcGF0aCgiRCIsICJTcGF0aWFsIiksImdyaWRfZWV6X3NmLnNocCIpKQoKI01ha2Ugc3VyZSBvZiB0aGluZ3MKCiMgZ3JpZF9lZXpfc2YgPC0gIHN0X3JlYWQoIi9Wb2x1bWVzL0VudGVycHJpc2UvRGF0YS9BY3Jvc3NCb3VuZGFyaWVzL0RhdGEvU3BhdGlhbC9ncmlkX3NmL2dyaWRfZWV6X3NmLnNocCIpCgojIHVuaXF1ZShncmlkX2Vlel9zZiRzdGF0ZSkKCiMgTm93IHNhdmUgaXQgYXMgYSBERiB0b28KCiMgZ3JpZF9lZXpfZGYgPC0gYXMuZGF0YS5mcmFtZShncmlkX2Vlel9zZikgJT4lCiAgIyBzZWxlY3Qoc3RhdGUsaW5kZXgpICU+JQogICMgbGVmdF9qb2luKG5lX2dyaWQsCiAgICAgICAgICAgICMgYnkgPSAiaW5kZXgiKQoKIyB3cml0ZV9jc3YoZ3JpZF9lZXpfZGYsIHBhc3RlMChteV9wYXRoKCJSIiwgIlBhcnRpYWwiKSwiZ3JpZF9lZXpfZGYuY3N2IikpCmBgYAoKCiMjIyBJbnRlcnBvbGF0aW9uIHJ1dGluZQoKSW4gdGhpcyBzdGVwIHdlIFtpbnRlcnBvbGF0ZV0oaHR0cHM6Ly9zd2lsa2UtZ2Vvc2NpZW5jZS5uZXQvcG9zdC9zcGF0aWFsX2ludGVycG9sYXRpb24vKSB0aGUgc3VydmV5IGRhdGEgd2l0aGluIHRoZSBwcmV2aW91c2x5IGNyZWF0ZWQgZ3JpZCBmb2xsb3dpbmcgYSBUcmlhbmd1bGFyIElycmVndWxhciBTdXJmYWNlIG1ldGhvZC4KCi0gV2UgcmVtb3ZlZCBjYXNlcyB3aGVyZSBgd3RjcHVlIDwgMGAKCiMjIyMgRnVuY3Rpb25zIG5lZWRlZAoKV2UgbmVlZCB0byBjcmVhdGUgYSBjb3VwbGUgb2YgZnVuY3Rpb25zIHRvIHJ1biB0aGUgd2hvbGUgcHJvY2VzcwoKIyMjIyMgSW50ZXJwb2xhdGlvbiBtYWluIGZ4ICh0aXMpLgoKVGhpcyBpcyB0aGUgbWFpbiBmdW5jdGlvbiB1c2VkIHRvIGludGVycG9sYXRlIHRoZSBkYXRhIHBlciB5ZWFyLiBJdCBmb2xsb3dzIGEgVHJpYW5ndWxhciBJcnJlZ3VsYXIgU3VyZmFjZSBtZXRob2QgdXNpbmcgdGhlIGBpbnRlcnA6OmludGVycCgpYCBmdW5jdGlvbi4gSWYgeW91IHdhbnQgdG8gc2VlIHRoZSBmdW5jdGlvbiBjbGljIG9uIGBjb2RlYAoKYGBge3IgaW50ZXJwb2xfZnVuY3Rpb24sIGV2YWwgPSBULCBlY2hvID0gVH0KCnRpcyA8LSBmdW5jdGlvbihpbnB1dF9kYXRhLCBncmlkLCB5ciwgdGF4YSwgcmVnKXsKICAKICAjIC0tLS0tLS0tLS0tLS0tLSAjCiAgIyBUZXN0aW5nCiAgIyBwcmludChwYXN0ZSh5cikpCiAgIyB5ciA9IDE5NzYKICAjIC0tLS0tLS0tLS0tLS0tLSAjCiAgCiAgIyBGaWx0ZXIgZGF0YQogIGRhdGEgPC0gaW5wdXRfZGF0YSAlPiUgCiAgICBmaWx0ZXIoeWVhciA9PSB5ciwKICAgICAgICAgICBzcHAgPT0gdGF4YSwKICAgICAgICAgICByZWdpb24gPT0gcmVnCiAgICApICU+JSAKICAgICMgQXZlcmFnZSBkdXBsaWNhdGVkIGhhdWxzIGluIHRoZSBzYW1lIHNwb3QKICAgIGdyb3VwX2J5KHJlZ2lvbix5ZWFyLHNwcCxsYXQsbG9uKSAlPiUKICAgIHN1bW1hcmlzZV9hdCh2YXJzKHd0Y3B1ZSksCiAgICAgICAgICAgICAgICAgbWVhbixuYS5ybSA9IFQpCiAgICAKICAjIE9ubHkgaW50ZXJwb2xhdGUgY2FzZXMgd2hlcmUgdGhlcmUgaXMgbW9yZSB0aGFuIDMgcm93cwogICMgTWFya2VkIGJ5IHRoZSBmdW5jdGlvbiAKICAgIGlmKG5yb3coZGF0YSkgPD0gMyl7CiAgICAgIGZpdF90aW4gPC0gdGliYmxlKCkKICAgIH1lbHNlewogICAgICAKICAgICAgIyBUcmlhbmd1bGFyIElycmVndWxhciBTdXJmYWNlCiAgICAgIGZpdF90aW4gPC0gaW50ZXJwOjppbnRlcnAoICMgdXNpbmcge2ludGVycH0KICAgICAgICB4ID0gZGF0YSRsb24sICAgICAgICAgICAjIHRoZSBmdW5jdGlvbiBhY3R1YWxseSBhY2NlcHRzIGNvb3JkaW5hdGUgdmVjdG9ycwogICAgICAgIHkgPSBkYXRhJGxhdCwKICAgICAgICB6ID0gZGF0YSR3dGNwdWUsCiAgICAgICAgeG8gPSBncmlkJGxvbiwgICAgICMgaGVyZSB3ZSBhbHJlYWR5IGRlZmluZSB0aGUgdGFyZ2V0IGdyaWQKICAgICAgICB5byA9IGdyaWQkbGF0LAogICAgICAgIG91dHB1dCA9ICJwb2ludHMiCiAgICAgICkgJT4lIAogICAgICAgIGJpbmRfY29scygpICU+JSAKICAgICAgICBiaW5kX2NvbHMoZ3JpZCkgJT4lCiAgICAgICAgbXV0YXRlKHllYXIgPSB5ciwKICAgICAgICAgICAgICAgcmVnaW9uID0gcmVnLAogICAgICAgICAgICAgICBzcHAgPSB0YXhhKSAlPiUgCiAgICAgICAgc2VsZWN0KGluZGV4LCBzdGF0ZSwgeWVhciwgcmVnaW9uLCBzcHAsIGxvbj14LCBsYXQ9eSwgdmFsdWUgPSB6KQogICAgICAKICAgIH0KICAgCiAgICByZXR1cm4oZml0X3RpbikKfQoKIyBUZXN0IG1lCiMgTmVlZHMgdmFyaWFibGVzIGluIENvbnRyb2wgcGFuZWwKIyBUZXN0IG5vIGRhdGE6ICJBbG9zYSBhZXN0aXZhbGlzIiwgcmVnID0gIk5vcnRoZWFzdCBVUyBGYWxsIiwgeXIgPSAxOTc0IAojIHRpcyhpbnB1dF9kYXRhID0gb2NlYW5fZGF0YSwgZ3JpZCA9IGdyaWRfZWV6X2RmLCB0YXhhID0gIklsbGV4IGlsbGVjZWJyb3N1cyIsIHJlZyA9ICJOb3J0aGVhc3QgVVMgRmFsbCIsIHlyID0gMTk3MykKCgoKIyBsYXBwbHkoeWVhcnMsdGlzLGlucHV0X2RhdGEgPSBvY2Vhbl9kYXRhLCBncmlkID0gZ3JpZF9lZXpfZGYsIHRheGEgPSAiSWxsZXggaWxsZWNlYnJvc3VzIiwgcmVnID0gcmVnaW9uc1syXSkKCmBgYAoKIyMjIyMgUnVuIGZ1bmN0aW9uCgpUaGlzIGlzIGEgc3ViLWZ1bmN0aW9uIHRoYXQgcnVucyB0aGUgYHRpcygpYCBmdW5jdGlvbiBieSB0YXhhIGFuZCByZWdpb24uIEl0IHNhdmVzIHRoZSBvdXRwdXQgYXMgYSAuY3N2IGZpbGUgZm9yIGVhY2ggc3BlY2llcy4gCgpgYGB7ciBpbnRlcnBvbF9ydW5fZnVuLCBldmFsID0gVCwgZWNobyA9IFR9CgoKcnVuX3RpcyA8LSBmdW5jdGlvbihpbnB1dF9kYXRhLCBncmlkLCB5ZWFycywgdGF4YSwgcmVnKXsKICAKICAKICAjIFJ1biB0aXMgZm9yIHNwZWNpZXMgYW5kIHN1cnZleXMKICBmb3IociBpbiAxOjIpewogICAgCiAgICBwYXJ0aWFsX2RmIDwtIGJpbmRfcm93cygKICAgICAgbGFwcGx5KHllYXJzLHRpcyxpbnB1dF9kYXRhID0gb2NlYW5fZGF0YSwgZ3JpZCA9IGdyaWRfZWV6X2RmLCB0YXhhID0gdGF4YSwgcmVnID0gcmVnaW9uc1tyXSkKICAgICkKICAgIAogICAgaWYociA9PSAxKXsKICAgICAgaGlzdG9yaWNfdGlmIDwtIHBhcnRpYWxfZGYKICAgIH1lbHNlewogICAgICBoaXN0b3JpY190aWYgPC0gYmluZF9yb3dzKGhpc3RvcmljX3RpZixwYXJ0aWFsX2RmKQogICAgfQogICAgCiAgfQogIAogICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICMgU2F2ZSBkYXRhc2V0IHBlciBzcGVjaWVzCiAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgCiAgIyBTZXQgZmlsZSBuYW1lCiAgbmFtZSA8LSBwYXN0ZTAoInRpZl8iLHN0cl9yZXBsYWNlKHRheGEsIiAiLCJfIiksIi5jc3YiKQogIAogICMgU2V0IHBhdGggbmFtZQogIHNhdmVfcGF0aCA8LSBteV9wYXRoKCJSIiwiUGFydGlhbC9JbnRlcnBvbGF0aW9uIikKICAKICAjIFNldCBjb21wbGV0ZSBwYXRoCiAgc2F2ZV9uYW1lIDwtIHBhc3RlMChzYXZlX3BhdGgsbmFtZSkKICAKICAjIENyZWF0ZSBmb2xkZXIgaWYgaXQgZG9lcyBub3QgZXhpc3QKICBpZihmaWxlLmV4aXN0cyhzYXZlX3BhdGgpID09IEYpewogICAgZGlyLmNyZWF0ZShzYXZlX3BhdGgpCiAgfQogIAogICMgIFNhdmUgZmlsZQogIHdyaXRlX2NzdihoaXN0b3JpY190aWYsc2F2ZV9uYW1lKQogIAogIHJldHVybl9tc2cgPC0gcGFzdGUoIkludGVycG9sYXRpb24gZG9uZSBmb3IiLCB0YXhhKQogIAogIHJldHVybihyZXR1cm5fbXNnKQogIAogIAp9CgojIFRlc3QgbWUKICAgICMgcnVuX3RpcyhpbnB1dF9kYXRhID0gb2NlYW5fZGF0YSwgZ3JpZCA9IGdyaWRfZWV6X2RmLCB0YXhhID0gIkNlbnRyb3ByaXN0aXMgc3RyaWF0YSIsIHllYXJzID0geWVhcnMsIHJlZyA9IHJlZ2lvbnMpCgpgYGAKCgojIyMjIFN1cnZleSBkYXRhCgpUaGUgaW50ZXJwb2xhdGlvbiB3YXMgZG9uZSB3aXRoIE5PQUEgTm9ydGhlYXN0IEZpc2hlcmllcyBTY2llbmNlIENlbnRlciBTcHJpbmcgYW5kIEZhbGwgQm90dG9tIFRyYXdsIFN1cnZleXMgW2RhdGFdKGh0dHBzOi8vd3d3LmZpc2hlcmllcy5ub2FhLmdvdi9yZWdpb24vbmV3LWVuZ2xhbmQtbWlkLWF0bGFudGljI3NjaWVuY2UpIHByb3ZpZGVkIGJ5IFtPY2VhbiBhZGFwdF0oaHR0cHM6Ly9vY2VhbmFkYXB0LnJ1dGdlcnMuZWR1LykuIERhdGEgd2FzIGFjY2Vzc2VkIHRyb3VnaCB0aGUgW0dpdGh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL3BpbnNreWxhYi9PY2VhbkFkYXB0KS4KCipJbiBwcmltYXJ5IHB1YmxpY2F0aW9ucyB1c2luZyBkYXRhIGZyb20gdGhlIGRhdGFiYXNlLCBwbGVhc2UgY2l0ZSBQaW5za3kgZXQgYWwuIDIwMTMuIE1hcmluZSB0YXhhIHRyYWNrIGxvY2FsIGNsaW1hdGUgdmVsb2NpdGllcy4gU2NpZW5jZSAzNDE6IDEyMzktMTI0MiBkb2k6IDEwLjExMjYvc2NpZW5jZS4xMjM5MzUyLCBhcyB3ZWxsIGFzIHRoZSBvcmlnaW5hbCBkYXRhIHNvdXJjZXMuKgoKLSBVc2luZyBvbmx5IHRoZSBOb3J0aGVhc3QgVVMgRmFsbCBhbmQgU3ByaW5nIGJvdHRvbSB0cmF3bCBzdXJ2ZXkgZGF0YSBmb3Igbm93CgojIyMjIyBTcGxpdHRpbmcgdXAgZGF0YQoKLSBObyBwYXJ0IG9uIHNwYXRpYWwgYW5hbHlzaXMuIENhbiBiZSBpZ25vcmVkLiAKClRoaXMgaXMganVzdCBhIHN1Yi1zdGVwIHRvIHNwbGl0IHVwIHRoZSBkYXRhIGludG8gc2luZ2xlIHNwZWNpZXMgZmlsZXMuIFRoaXMgbWFrZXMgdGhlIGFwcCBmYXN0ZXIgYXMgaXQgb25seSBuZWVkcyB0byBsb2FkIHNwZWNpZXMgc3BlY2lmaWMgZGF0YSwgcmF0aGVyIHRoYW4gYWxsIHRoZSBkYXRhIGF0IGRlIGJlZ2lubmluZy4gCgpgYGB7ciBkYXRfZXhwbG9kZWQsIGV2YWwgPSBGLCBlY2hvID0gRiwgZmlnLndpZHRoID0gOX0KCm9jZWFuX2RhdGEgPC0gcmVhZFJEUygiL1ZvbHVtZXMvRW50ZXJwcmlzZS9EYXRhL3BpbnNreWxhYi1PY2VhbkFkYXB0LTk2NmFkZjAvZGF0YV9jbGVhbi9kYXRfZXhwbG9kZWQucmRzIikgIyU+JSAKICAjIGZpbHRlcihzcHAgPT0gIkNlbnRyb3ByaXN0aXMgc3RyaWF0YSIsCiAgICAgICAjIHJlZ2lvbiAlaW4lIGMoIk5vcnRoZWFzdCBVUyBGYWxsIiAsICJOb3J0aGVhc3QgVVMgU3ByaW5nIikpICNObyBtb3JlIHNlYXNvbnMKCgpzcHBfZGF0YSA8LSBmdW5jdGlvbihzcHApewogIAogIG5hbWVfc2F2ZSA8LSBwYXN0ZTAobXlfcGF0aCgiRCIsIlNwcC9PYnNlcnZhdGlvbiIpLCJvYnNfIixzdHJfcmVwbGFjZShzcHBbMV0sICIgIiwgIl8iKSwiLmNzdiIpCgpvY2Vhbl9kYXRhICU+JSAKICBmaWx0ZXIoc3BwID09IHNwcCwKICAgICAgIHJlZ2lvbiAlaW4lIGMoIk5vcnRoZWFzdCBVUyBGYWxsIiAsICJOb3J0aGVhc3QgVVMgU3ByaW5nIikKICAgICAgICkgJT4lIAogIHdyaXRlX2NzdiguLCBuYW1lX3NhdmUpCiAgCn0KCnNwcF9saXN0IDwtIG9jZWFuX2RhdGEgJT4lIAogIGZpbHRlcihyZWdpb24gJWluJSByZWdpb25zLAogICAgICAgICBzcHAgIT0gIk5BIikgJT4lIAogIHB1bGwoc3BwKSAlPiUgCiAgdW5pcXVlKCkKICAKCmxhcHBseShzcHBfbGlzdCwgc3BwX2RhdGEpCgoKc3Vic2V0X2RhdGEgPC0gb2NlYW5fZGF0YSAlPiUgCiAgZmlsdGVyKHNwcCA9PSAiQ2VudHJvcHJpc3RpcyBzdHJpYXRhIiwKICAgICAgIHJlZ2lvbiAlaW4lIGMoIk5vcnRoZWFzdCBVUyBGYWxsIiAsICJOb3J0aGVhc3QgVVMgU3ByaW5nIikKICAgICAgICkKCmdncGxvdCgpICsKICBnZW9tX3BvaW50KGRhdGEgPSBzdWJzZXQoc3Vic2V0X2RhdGEsIHd0Y3B1ZSA9IDAuMCksCiAgICAgICAgICAgICBhZXMoCiAgICAgICAgICAgICAgIHggPSBsb24sCiAgICAgICAgICAgICAgIHkgPSBsYXQKICAgICAgICAgICAgICksCiAgICAgICAgICAgICBjb2xvciA9ICJncmV5OTUiCiAgKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3Vic2V0KHN1YnNldF9kYXRhLCB3dGNwdWUgPiAwKSwKICAgICAgICAgICAgIGFlcygKICAgICAgICAgICAgICAgeCA9IGxvbiwKICAgICAgICAgICAgICAgeSA9IGxhdCwKICAgICAgICAgICAgICAgY29sb3IgPSBsb2cxMCh3dGNwdWUpCiAgICAgICAgICAgICApLAogICAgICAgICAgICAgc2l6ZSA9IDEKICApICsKICBzY2FsZV9jb2xvcl9kaXN0aWxsZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICBndWlkZV9sZWdlbmQodGl0bGUgPSAiV0NQVUUgcGVyIEhhdWwgKGxvZzEwKSIpKSArIAogIGNvb3JkX3NmKHhsaW0gPSBjKC03NiwgLTY1KSx5bGltID0gYygzNSwgNDUpKSArCiAgTXlGdW5jdGlvbnM6Om15X2dndGhlbWVfbSgpICsKICBmYWNldF93cmFwKH5yZWdpb24pCgpgYGAKCiMjIyMgQ29udHJvbCBQYW5uZWwKClRoaXMgaXMgd2hlcmUgd2UgbG9hZCB0aGUgcmVxdWlyZWQgZGF0YSBhbmQgcHJlcGFyZSB0byBydW4gdGhlIGludGVycG9sYXRpb24gZnVuY3Rpb24uIE5vdGUgdGhhdCBzb21lIG9mIHRoZSBkYXRhIGhlcmUgaGFzIGJlZW4gcHJldmlvdXNseSBjcmVhdGVkIAoKYGBge3IgY29udHJvX3Bhbm5lbCwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKIyBMb2FkIGdyaWQgZGYKZ3JpZF9lZXpfZGYgPC0gbXlfcGF0aCgiRCIsIlNwYXRpYWwiLCJncmlkX2Vlel9kZi5jc3YiLCByZWFkID0gVCkKCiMgUnVuIGludGVycG9sYXRpb24gZm9yIGFsbCB5ZWFycwp5ZWFycyA8LSBzZXEoMTk3MywyMDE5LDEpCgojIHJlZ2lvbnMKcmVnaW9ucyA8LSBjKCJOb3J0aGVhc3QgVVMgRmFsbCIgLCAiTm9ydGhlYXN0IFVTIFNwcmluZyIpCgojIHNwZWNpZXMgbGlzdApzcHAgPC0gb2NlYW5fZGF0YSAlPiUgCiAgZmlsdGVyKHJlZ2lvbiAlaW4lIHJlZ2lvbnMsCiAgICAgICAgIHNwcCAhPSAiTkEiKSAlPiUgCiAgcHVsbChzcHApICU+JSAKICB1bmlxdWUoKQoKCiMgRG91YmxlIGNoZWNrIHJ1bnMKCnNwcF9ydW5zIDwtIHRpYmJsZSh0YXhhID0gKGxpc3QuZmlsZXMobXlfcGF0aCgiUiIsIlBhcnRpYWwvSW50ZXJwb2xhdGlvbiIpKSkpICU+JQogIG11dGF0ZSgKICAgIHRheGEgPSBzdHJfcmVtb3ZlKHRheGEsICJ0aWZfIiksCiAgICB0YXhhID0gc3RyX3JlbW92ZSh0YXhhLCAiLmNzdiIpLAogICAgdGF4YSA9IHN0cl9yZXBsYWNlKHRheGEsICJfIiwgIiAiKQogICkgCgojIE1pc3NpbmcgcnVucwpzcHAgPC0gdGliYmxlKHRheGE9c3BwKSAlPiUgCiAgYW50aV9qb2luKHNwcF9ydW5zKSAlPiUgCiAgcHVsbCh0YXhhKQoKCmBgYAoKIyMjIyBSdW4gcm91dGluZQoKSGVyZSB3ZSBqdXN0IHJ1biB0aGUgcm91dGluZSBmb3IgZWFjaCBvZiB0aGUgc3BlY2llcyBwcmVzZW50IGluIHRoZSBOb3J0aGVhc3QgVVMgRmFsbCBhbmQgU3ByaW5nIHN1cnZleXMgYmV0d2VlbiAxOTczIGFuZCAyMDE5LiAKCi0gTm90ZSB0aGVyZSBhcmUgNDMgaWRlbnRpZmllZCB0YXhhCi0gU29tZSB0YXhhIGRvIG5vdCBoYXZlIHByZXNlbmNlIGRhdGEgaW4gc29tZSB5ZWFycwoKYGBge3IgcnVuX3JvdXRpbmUsIGV2YWwgPSBULCBlY2hvID0gVH0KCiMgc2luZ2xlIHNwZWNpZXMgcnVuCiMgcnVuX3RpcyhpbnB1dF9kYXRhID0gb2NlYW5fZGF0YSwKIyAgICAgICAgIGdyaWQgPSBncmlkX2Vlel9kZiwKIyAgICAgICAgIHllYXJzID0geWVhcnMsCiMgICAgICAgICByZWcgPSByZWdpb25zLAojICAgICAgICAgdGF4YSA9ICJJbGxleCBpbGxlY2Vicm9zdXMiCiMgKQoKCiMgUnVuIHRoZW0gYWxsIGluIHBhcmFsbGVsCmxhcHBseShzcHAsCiAgICAgICAgICAgICAgICAgICBydW5fdGlzLCAKICAgICAgICAgICAgICAgICAgIGlucHV0X2RhdGEgPSBvY2Vhbl9kYXRhLAogICAgICAgICAgICAgICAgICAgZ3JpZCA9IGdyaWRfZWV6X2RmLAogICAgICAgICAgICAgICAgICAgeWVhcnMgPSB5ZWFycywKICAgICAgICAgICAgICAgICAgIHJlZyA9IHJlZ2lvbnMKKQoKCmBgYAoKIyBSZXN1bHRzCgpSZXN1bHRzIGFyZSBub3cgZm9yIGVpZ2h0IHNwZWNpZXMgbWFuYWdlZCB1bmRlciBNaWQtQXRsYW50aWMgQ291bmNpbCBNYW5hZ2VtZW50IFBsYW5zIGFjY29yZGluZyB0byBbTk9BQV0oaHR0cHM6Ly93d3cuZmlzaGVyaWVzLm5vYWEuZ292L25ldy1lbmdsYW5kLW1pZC1hdGxhbnRpYy9jb21tZXJjaWFsLWZpc2hpbmcvbmV3LWVuZ2xhbmQtbWlkLWF0bGFudGljLWZpc2hlcnktbWFuYWdlbWVudC1wbGFucykuCgoKKlNjb21iZXIgc2NvbWJydXMqLCAqUGVwcmlsdXMgdHJpYWNhbnRodXMqIChidXR0ZXJmaXNoKSwgKklsbGV4IGlsbGVjZWJyb3N1cyogKHNob3J0ZmluIHNxdWlkKSwgKlBhcmFsaWNodGh5cyBkZW50YXR1cyogKHN1bW1lciBmbG91bmRlciksICpTdGVub3RvbXVzIGNocnlzb3BzKiAoU2Nvb3ApLCAqQ2VudHJvcHJpc3RpcyBzdHJpYXRhKiAoYmxhY2sgc2VhIGJhc3MpLCAqUG9tYXRvbXVzIHNhbHRhdHJpeCogKEJsdWVmaXNoKSwgKkxvcGhvbGF0aWx1cyBjaGFtYWVsZW9udGljZXBzKiAoR29sZGVuIHRpbGVmaXNoKSwgKkNhdWxvbGF0aWx1cyBtaWNyb3BzKiAoYmx1ZWxpbmUgdGlsZWZpc2gpIGFuZCAqQ2x1cGVhIGhhcmVuZ3VzKgoKCmBgYHtyIGxvYWRfZGF0YSwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKIyBTcGVjaWVzIGRhdGEKCiMgTG9hZCBpbnRlcnBvbGF0ZWQgZGF0YQojICJDZW50cm9wcmlzdGlzIHN0cmlhdGEiCiMgCiMgaGlzdG9yaWNfdGlmIDwtIG15X3BhdGgoIlIiLCJQYXJ0aWFsL0ludGVycG9sYXRpb24iLCJ0aWZfQ2VudHJvcHJpc3Rpc19zdHJpYXRhLmNzdiIsIHJlYWQgPSBUKSAlPiUgCiMgICBtdXRhdGUoc3RhdGUgPSBzdHJfdG9fc2VudGVuY2Uoc3RhdGUpKQoKCiMgTXVsdGlwbGUgc3BlY2llcwoKIyBNYW5hZ2VkIHNwZWNpZXMgYnkgTWlkLUF0bGFudGljIENvdW5jaWwgTWFuYWdlbWVudCBQbGFucywgYW5kIFN0YXRlIHdhdGVycwojIGh0dHBzOi8vd3d3LmZpc2hlcmllcy5ub2FhLmdvdi9uZXctZW5nbGFuZC1taWQtYXRsYW50aWMvY29tbWVyY2lhbC1maXNoaW5nL25ldy1lbmdsYW5kLW1pZC1hdGxhbnRpYy1maXNoZXJ5LW1hbmFnZW1lbnQtcGxhbnMKClNwZWNpZXMgPC0gYygKICAjICJTY29tYmVyIHNjb21icnVzIiwKICAjICJEb3J5dGV1dGhpcyAoQW1lcmlnbykgcGVhbGVpaSIsICNsb25nZmluIHNxdWlkIFdFIERPTlQgSEFWRSBJVAogICMgIlBlcHJpbHVzIHRyaWFjYW50aHVzIiwgIyBidXR0ZXJmaXNoCiAgIyAiSWxsZXggaWxsZWNlYnJvc3VzIiwgI3Nob3J0ZmluIHNxdWlkCiAgIlBhcmFsaWNodGh5cyBkZW50YXR1cyIsICNzdW1tZXIgZmxvdW5kZXIKICAiU3Rlbm90b211cyBjaHJ5c29wcyIsICNTY3VwIgogICJDZW50cm9wcmlzdGlzIHN0cmlhdGEiIywgIyBibGFjayBzZWEgYmFzcwogICMgIlBvbWF0b211cyBzYWx0YXRyaXgiLCAjIEJsdWVmaXNoCiAgIyAiTG9waG9sYXRpbHVzIGNoYW1hZWxlb250aWNlcHMiLCAjZ29sZGVuIHRpbGVmaXNoCiAgIyAiQ2F1bG9sYXRpbHVzIG1pY3JvcHMiLCAjYmx1ZWxpbmUgdGlsZWZpc2gKICAjICJDbHVwZWEgaGFyZW5ndXMiICMgQXRsYW50aWMgaGVycmluZyAoSm9pbnRseSBpbiBTdGF0ZSBhbmQgRmVkZXJhbCBXYXRlcnMpCiAgKQoKCnNwcF9wYXRocyA8LSBsaXN0LmZpbGVzKG15X3BhdGgoIlIiLGV4dHJhX3BhdGggPSAiUGFydGlhbC9JbnRlcnBvbGF0aW9uIikpCgojIFNvbWUgZ2liaXJpcyBmb3IgbmFtZXMKdGF4b25fbGlzdCA8LSBnc3ViKCJfIiwiICIsc3BwX3BhdGhzKQp0YXhvbl9saXN0IDwtIGdzdWIoInRpZiAiLCIiLHRheG9uX2xpc3QpCnRheG9uX2xpc3QgPC0gZ3N1YigiLmNzdiIsIiIsdGF4b25fbGlzdCkKCnRheG9uX2xpc3QgPC0gdGF4b25fbGlzdFt0YXhvbl9saXN0ICVpbiUgU3BlY2llc10KCiMgTm93IHNldCBhIGxpc3Qgb2YgZmlsZXMgdG8gcmVhZAp0YXhvbl9yZWFkIDwtIHBhc3RlMCgidGlmXyIsdGF4b25fbGlzdCwiLmNzdiIpCnRheG9uX3JlYWQgPC0gZ3N1YigiICIsIl8iLHRheG9uX3JlYWQpCgp0YXhvbl9yZWFkIDwtIHNwcF9wYXRoc1tzcHBfcGF0aHMgJWluJSB0YXhvbl9yZWFkXQoKdGF4b25fcmVhZCA8LSBwYXN0ZTAobXlfcGF0aCgiUiIsZXh0cmFfcGF0aCA9ICJQYXJ0aWFsL0ludGVycG9sYXRpb24iKSx0YXhvbl9yZWFkKQoKCiMgTG9hZCBhbGwgc3AgaW4gb25lIHRhYmxlCmhpc3RvcmljX3NwcCA8LSBiaW5kX3Jvd3MobGFwcGx5KHRheG9uX3JlYWQsIGZyZWFkKSkgJT4lIAogIG11dGF0ZShzdGF0ZSA9IHN0cl90b19zZW50ZW5jZShzdGF0ZSkpCgoKdW5pcXVlKGhpc3RvcmljX3NwcCRzcHApCgojIFNwYXRpYWwgZGF0YQpTdGF0ZXMgPC0gYygibWFpbmUiLCAibmV3IGhhbXBzaGlyZSIsICJtYXNzYWNodXNldHRzIiwgImNvbm5lY3RpY3V0IiwgInJob2RlIGlzbGFuZCIsICJuZXcgeW9yayIsICJuZXcgamVyc2V5IiwgImRlbGF3YXJlIiwgIm1hcnlsYW5kIiwgInZpcmdpbmlhIiwgIm5vcnRoIGNhcm9saW5hIikgCgojIFVTIFN0YXRlIE1hcCAobGFuZCkKbGFuZF9zZiA8LSBzdF9hc19zZihtYXAoInN0YXRlIiwgcGxvdCA9IEZBTFNFLCBmaWxsID0gVFJVRSkpICU+JSAKICBmaWx0ZXIoSUQgJWluJSBTdGF0ZXMpICU+JSAKICBtdXRhdGUoYWJyZXYgPSBjKCJDVCIsIkRFIiwiTUUiLCJNRCIsIk1BIiwiTkgiLCJOSiIsIk5ZIiwiTkMiLCJSSSIsIlZBIiksCiAgICAgICAgIHN0YXRlID0gc3RyX3RvX3NlbnRlbmNlKElEKQogICAgICAgICApCgojIFBlcmlvZHMKcGVyaW9kcyA8LXRpYmJsZSgKICBvcmRlciA9IGMocmVwKCJhIiwxMiksCiAgICAgICAgICAgIHJlcCgiYiIsMTIpLAogICAgICAgICAgICByZXAoImMiLDEyKSwKICAgICAgICAgICAgcmVwKCJkIiwxMSkKICApLAogIGxhYmVsID0gYyhyZXAoIjE5NzMtMTk4NCIsMTIpLAogICAgICAgICAgICByZXAoIjE5ODUtMTk5NiIsMTIpLAogICAgICAgICAgICByZXAoIjE5OTctMjAwOCIsMTIpLAogICAgICAgICAgICByZXAoIjIwMDktMjAxOSIsMTEpCiAgKSwKICB5ZWFyID0gYyhzZXEoMTk3MywxOTg0LDEpLAogICAgICAgICAgIHNlcSgxOTg1LDE5OTYsMSksCiAgICAgICAgICAgc2VxKDE5OTcsMjAwOCwxKSwKICAgICAgICAgICBzZXEoMjAwOSwyMDE5LDEpCiAgKQopCgoKc3RhdGVfbGF0IDwtIGhpc3RvcmljX3NwcCAlPiUKICBncm91cF9ieShzdGF0ZSkgJT4lIAogIHN1bW1hcmlzZSgKICAgIG9yZGVyID0gbWVhbihsYXQpCiAgKSAlPiUgCiAgbXV0YXRlKGFicmV2ID0gYygiQ1QiLCJERSIsIk1FIiwiTUQiLCJNQSIsIk5IIiwiTkoiLCJOWSIsIk5DIiwiUkkiLCJWQSIpCiAgKSAlPiUgCiAgYXJyYW5nZShkZXNjKG9yZGVyKSkgJT4lIAogIG11dGF0ZShvcmRlcj0gbGV0dGVyc1sxOjExXSkKCgoKIyBTdGF0ZSBwYWxsZXQKCnN0YXRlX3BhbGxldCA8LSBjKHdlc19wYWxldHRlKG4gPSA1LCBuYW1lID0gIkRhcmplZWxpbmcxIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZXNfcGFsZXR0ZShuID0gNSwgbmFtZSA9ICJEYXJqZWVsaW5nMiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB3ZXNfcGFsZXR0ZShuID0gMiwgbmFtZSA9ICJHcmFuZEJ1ZGFwZXN0MSIpCiAgICAgICAgICAgICAgICAgICIjRkQ2NDY3IgogICAgICAgICAgICAgICAgICApCgoKCiMgcHJpbnQgZm9yIG5vdGVib29rCmhlYWQoaGlzdG9yaWNfc3BwKQpgYGAKCiMjIEF2ZXJhZ2UgcHJvcG9ydGlvbgoKVGhpcyBtYXAgc2hvd3MgdGhlIGFnZ3JlZ2F0ZWQgZXh0cmFwb2xhdGVkIHZhbHVlIGZyb20gYWxsIHRocmVlIHNwZWNpZXMgcGVyIFN0YXRlIGF2ZXJhZ2UgYWNyb3NzIHRoZSB3aG9sZSBzdHVkeSBwZXJpb2Qgd2l0aGluIGVhY2ggU3RhdGUncyB3YXRlci4KCipOb3RlOiogVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBhIHN1cHBsZW1lbnRhbCBmaWd1cmUKCmBgYHtyIGFyZWFfbWFwX3N0YXRlLCBldmFsID0gVCwgZWNobyA9IFQsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMn0KCiBkYXRhX2dyaWQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieShzdGF0ZSxsYXQsbG9uLHJlZ2lvbikgJT4lIAogIHN1bW1hcmlzZShzdW0gPSBzdW0odmFsdWUsbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgIyBzdW0gb2YgYWxsIHNwZWNpZXMKICBncm91cF9ieShzdGF0ZSxsYXQsbG9uLHJlZ2lvbikgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gbWVhbihzdW0sbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAjIGF2ZXJhZ2Ugb2YgYWxsIHllYXJzCgoKZ2dwbG90KGRhdGEgPSBzdWJzZXQoZGF0YV9ncmlkLCAhaXMubmEobWVhbikpKSArCiAgZ2VvbV90aWxlKAogICAgYWVzKAogICAgICB4ID0gbG9uLAogICAgICB5ID0gbGF0LAogICAgICBmaWxsID0gbWVhbiwKICAgICAgY29sID0gbWVhbgogICAgKQogICkgKwogIGdlb21fc2YoZGF0YSA9IGxhbmRfc2YsIGFlcygpKSArCiAgZmFjZXRfd3JhcCh+IHN0YXRlICArICByZWdpb24sCiAgICAgICAgICAgICBuY29sID0gNCkgKwogIGxhYnMoeCA9ICJMb25naXR1ZGUiLCB5ID0gIkxhdGl0dWRlIikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpcygiTWVhbiBJbnRlcnBvbGF0aW9uIiwgYWxwaGEgPSAwLjgpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzKCJNZWFuIEludGVycG9sYXRpb24iLCBhbHBoYSA9IDAuOCkgKwogIHRoZW1lX2J3KCkKYGBgCgojIyBQcm9wb3J0aW9uIENoYW5nZQoKSGVyZSB3ZSBzaG93IHRoZSBhdmVyYWdlIHByb3BvcnRpb24gb2YgdGhlIGludGVycG9sYXRpb24gYnkgU3RhdGUgYW5kIHRpbWUgcGVyaW9kLiBUaW1lIHBlcmlvZHMgd2VyZSBhcmJpdHJhcnkgZGVmaW5lZCBhczsKCi0gRWFybHk7IDE5NzMgdG8gMTk4NAotIE1pZDsgMTk4NSB0byAxOTk3Ci0gTGF0ZTsgMTk5OCB0byAyMDExCi0gTm93OyAyMDEyIHRvIDIwMTkKCipOb3RlczoqIEZpZ3VyZSByZXByZXNlbnRzIHRoZSAqKlNwcmluZyoqIHN1cnZleS4gVGhpcyBjb21wdXRhdGlvbiBjb25zaWRlcnMgdGhlIE92ZXJsYXBwaW5nIG9mIHN0YXRlIHdhdGVycy4KCiMjIyBEeW5hbWljIGZpZ3VyZTogQWdncmVnYXRlZCBQcm9wb3J0aW9uYWwgY2hhbmdlIHBlciBzdXJ2ZXkKCmBgYHtyIGFyZWFfbWFwX2FnZ3JlZ2F0ZWQsIGV2YWwgPSBULCBlY2hvID0gVCwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQ9Nn0KCnRvdGFsX2ZpdGVkIDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoeWVhcixyZWdpb24pICU+JSAKICBzdW1tYXJpc2UodG90YWxfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09VCksLmdyb3VwcyA9ICJkcm9wIikKCgpzdGF0ZV9maXQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieShzdGF0ZSx5ZWFyLHJlZ2lvbikgJT4lIAogIHN1bW1hcmlzZShzdGF0ZV92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT0gVCksIC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICBsZWZ0X2pvaW4odG90YWxfZml0ZWQsCiAgICAgICAgICAgIGJ5ID0gYygieWVhciIsInJlZ2lvbiIpKSAlPiUKICBtdXRhdGUocGVyY2VudGFnZSA9IHN0YXRlX3ZhbHVlL3RvdGFsX3ZhbHVlKjEwMCkgJT4lIAogIGxlZnRfam9pbihwZXJpb2RzLAogICAgICAgICAgICBieSA9ICJ5ZWFyIikgJT4lIAogIGdyb3VwX2J5KHN0YXRlLG9yZGVyLGxhYmVsLHJlZ2lvbikgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BlciA9IHJvdW5kKG1lYW4ocGVyY2VudGFnZSkpLC5ncm91cHMgPSAiZHJvcCIpCgojIGNoZWNrIHBlcmNlbnRhZ2VzCiMgc3RhdGVfZml0ICU+JSAKIyAgIGdyb3VwX2J5KHBlcmlvZCkgJT4lIAojICAgc3VtbWFyaXNlKHN1bShtZWFuX3BlcikpCgoKcCA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4oc3RhdGVfZml0LAogICAgICAgICAgICBieSA9ICJzdGF0ZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgIyBnZW9tX3NmKGFlcyhmaWxsID0gbWVhbl9wZXIpKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IG1lYW5fcGVyLCB0ZXh0ID0gcGFzdGUoc3RhdGUsIG1lYW5fcGVyLCIlIG9mIHByb3BvcnRpb24iKSkpICsKICB2aXJpZGlzOjpzY2FsZV9maWxsX3ZpcmlkaXMoIkF2ZXJhZ2UgcHJvcG9ydGlvbiBwZXIgU3RhdGUiLCBhbHBoYSA9IDAuOCkgKwogIGZhY2V0X3dyYXAofiByZWdpb24gKyBsYWJlbCwgCiAgICAgICAgICAgICBucm93ID0gMikgKwogIGxhYnMoeCA9ICJMYXRpdHVkZSIsIAogICAgICAgeSA9ICJMb25naXR1ZGUiKSArCiAgbXlfZ2d0aGVtZV9wKGZhY2V0X3R4X3MgPSAxMiwKICAgICAgICAgICAgICAgbGVnX3BvcyA9ICJib3R0b20iKSArCiAgdGhlbWUobGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMSwibGluZSIpKSArCiAgdGhlbWVfZGFyaygpCgpnZ3Bsb3RseShwLAogICAgICAgICB0b29sdGlwID0gInRleHQiLAogICAgICAgICBkeW5hbWljVGlja3MgPSBGQUxTRSkgJT4lIAogICAgc3R5bGUoaG92ZXJsYWJlbCA9IGxpc3QoYmdjb2xvciA9ICJ3aGl0ZSIpLCBob3Zlcm9uID0gImZpbGwiKQoKCmBgYAoKCiMjIyBQYXBlciBmaWd1cmU7IFBlciBzcGVjaWVzIG1hcHMKCmBgYHtyIHBhcGVyX2ZpZ3VyZV9hcmVhX21hcCwgZXZhbCA9IEYsIGVjaG8gPSBULCByZXN1bHRzPSdoaWRlJ30KCnRvdGFsX2ZpdGVkIDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoeWVhcixyZWdpb24sc3BwKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPVQpLC5ncm91cHMgPSAiZHJvcCIpCgoKc3RhdGVfZml0IDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUseWVhcixyZWdpb24sc3BwKSAlPiUgCiAgc3VtbWFyaXNlKHN0YXRlX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPSBUKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIGxlZnRfam9pbih0b3RhbF9maXRlZCwKICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwicmVnaW9uIiwic3BwIikpICU+JQogIG11dGF0ZShwZXJjZW50YWdlID0gc3RhdGVfdmFsdWUvdG90YWxfdmFsdWUqMTAwKSAlPiUgCiAgbGVmdF9qb2luKHBlcmlvZHMsCiAgICAgICAgICAgIGJ5ID0gInllYXIiKSAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUsb3JkZXIsbGFiZWwscmVnaW9uLHNwcCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BlciA9IHJvdW5kKG1lYW4ocGVyY2VudGFnZSkpLC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICAjT25seSBzaG93IHJlc3VsdHMgZm9yIHNwcmluZwogIGZpbHRlcihzdHJfZGV0ZWN0KHJlZ2lvbiwiU3ByaW5nIikpICU+JSAKICBtdXRhdGUoc3BwID0gZ3N1YigiICIsIlxuIixzcHApKQoKIyBUaGUgcGxvdAptYXBfcGxvdCA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4oc3RhdGVfZml0LAogICAgICAgICAgICBieSA9ICJzdGF0ZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IG1lYW5fcGVyKSkgKwogIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcygiQXZlcmFnZSBwcm9wb3J0aW9uIHBlciBTdGF0ZSIsIGFscGhhID0gMC44KSArCiAgZmFjZXRfZ3JpZChzcHAgfiBsYWJlbCkgKwogIGxhYnMoeCA9ICJMb25naXR1ZGUiLCAKICAgICAgIHkgPSAiTGF0aXR1ZGUiKSArCiAgbXlfZ2d0aGVtZV9wKGZhY2V0X3R4X3MgPSAyMCwKICAgICAgICAgICAgICAgbGVnX3BvcyA9ICJib3R0b20iLAogICAgICAgICAgICAgICBheHhfdHhfYW5nID0gNDUsCiAgICAgICAgICAgICAgIGF4X3R4X3MgPSAxMiwKICAgICAgICAgICAgICAgYXhfdGxfcyA9IDE4LAogICAgICAgICAgICAgICBoanVzdCA9IDEpICsKICB0aGVtZShsZWdlbmQua2V5LndpZHRoID0gdW5pdCg0LCJsaW5lIikpIAoKCiAgZ2dzYXZlKGZpbGVuYW1lID0gInByb3BvcnRpb25fY2hnX3NwcC5qcGciLAogICAgICAgICBwbG90ID0gbWFwX3Bsb3QsCiAgICAgICAgIHBhdGggPSBteV9wYXRoKCJSIiwiRmlndXJlcyIpLAogICAgICAgICB3aWR0aCA9IDE0LAogICAgICAgICBoZWlnaHQgPSAxNAogICAgICAgICApCgoKYGBgCgoKIVtQcm9wb3J0aW9uIGNoYW5nZSBwZXIgc3BlY2llcyBtYXAgZm9yIHBhcGVyXSgvVm9sdW1lcy9FbnRlcnByaXNlL0RhdGEvQWNyb3NzQm91bmRhcmllcy9SZXN1bHRzL0ZpZ3VyZXMvcHJvcG9ydGlvbl9jaGdfc3BwLmpwZykKCgojIyMgUGFwZXIgZmlndXJlOiBBZ2dyZWdhdGVkIFByb3BvcnRpb25hbCBjaGFuZ2UKCmBgYHtyIGFyZWFfbWFwX2FnZ3JlZ2F0ZWRfZm9ybWFucywgZXZhbCA9IFQsIGVjaG8gPSBULCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodD02fQoKdG90YWxfZml0ZWQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieSh5ZWFyLHJlZ2lvbikgJT4lIAogIHN1bW1hcmlzZSh0b3RhbF92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT1UKSwuZ3JvdXBzID0gImRyb3AiKQoKCnN0YXRlX2ZpdCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHllYXIscmVnaW9uKSAlPiUgCiAgc3VtbWFyaXNlKHN0YXRlX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPSBUKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIGxlZnRfam9pbih0b3RhbF9maXRlZCwKICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwicmVnaW9uIikpICU+JQogIG11dGF0ZShwZXJjZW50YWdlID0gc3RhdGVfdmFsdWUvdG90YWxfdmFsdWUqMTAwKSAlPiUgCiAgbGVmdF9qb2luKHBlcmlvZHMsCiAgICAgICAgICAgIGJ5ID0gInllYXIiKSAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUsb3JkZXIsbGFiZWwscmVnaW9uKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcGVyID0gcm91bmQobWVhbihwZXJjZW50YWdlKSksLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KHJlZ2lvbiwiU3ByaW5nIikpCgoKYWdnX21hcCA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4oc3RhdGVfZml0LAogICAgICAgICAgICBieSA9ICJzdGF0ZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IG1lYW5fcGVyKSkgKwogIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcygiQXZlcmFnZSBwcm9wb3J0aW9uIHBlciBTdGF0ZSIsIGFscGhhID0gMC44KSArCiAgZmFjZXRfd3JhcCh+IGxhYmVsLCBucm93ID0gMSkgKwogIGxhYnMoeCA9ICJMb25naXR1ZGUiLCAKICAgICAgIHkgPSAiTGF0aXR1ZGUiKSArCiAgbXlfZ2d0aGVtZV9wKGZhY2V0X3R4X3MgPSAxNiwKICAgICAgICAgICAgICAgbGVnX3BvcyA9ICJib3R0b20iLAogICAgICAgICAgICAgICBsZWdfdGxfcyA9IDE0LAogICAgICAgICAgICAgICBheF90eF9zID0gMTAsCiAgICAgICAgICAgICAgIGF4X3RsX3MgPSAxNCkgKwogIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDIsImxpbmUiKSkgCgogIGdnc2F2ZShmaWxlbmFtZSA9ICJwcm9wb3J0aW9uX2NoZ19hZ2cuanBnIiwKICAgICAgICAgcGxvdCA9IGFnZ19tYXAsCiAgICAgICAgIHBhdGggPSBteV9wYXRoKCJSIiwiRmlndXJlcyIpLAogICAgICAgICB3aWR0aCA9IDksCiAgICAgICAgIGhlaWdodCA9IDUKICAgICAgICAgKQoKYGBgCgohW1Byb3BvcnRpb24gY2hhbmdlIGFnZ3JlZ2F0ZWQgYWxsIHNwZWNpZXMgbWFwIGZvciBwYXBlcl0oL1ZvbHVtZXMvRW50ZXJwcmlzZS9EYXRhL0Fjcm9zc0JvdW5kYXJpZXMvUmVzdWx0cy9GaWd1cmVzL3Byb3BvcnRpb25fY2hnX2FnZy5qcGcpCgoKIyMgQXJlYSBwbG90CgpUaGlzIGdyYXBoIHNob3dzIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBpbnRlcnBvbGF0aW9uIHZhbHVlIGVhY2ggU3RhdGUgaGFzIG92ZXIgdGltZS4KCipOb3RlOiogVGhpcyBwbG90IGlzIGludGVyYWN0aXZlLiBGb3IgZWFzZSBjb21wYXJpc29uIGJldHdlZW4gU3RhdGVzIHlvdSBjYW47CgotICpPbmUqIGNsaWNrIG9uIGFueSBTdGF0ZSB0byAqcmVtb3ZlKiBpdCBmcm9tIHRoZSBwbG90IAotICpUd28qIGNsaWNrcyBvbiBhbnkgU3RhdGUgdG8gKmlzb2xhdGUgaXQqIGZyb20gdGhlIHBsb3QgKG90aGVyIHN0YXRlcyBjYW4gdGhlbiBiZSBhZGRlZCBieSBqdXN0IGNsaWNraW5nIG9uIHRoZW0pLgotIFRoZSBib3R0b20gcGFuZWwgYWxsb3dzIHlvdSB0byByZWR1Y2UgdGhlIHRpbWUgZnJhbWUKCiMjIyBEeW5hbWljIGFnZ3JlZ2F0ZWQgcGxvdAoKYGBge3IgZHluYW1pY19hcmVhX3Bsb3QsIGV2YWwgPSBULCBlY2hvID0gVCwgZmlnLmhlaWdodCA9IDEwLCBmaWcud2lkdGggPSAxMH0KCnRvdGFsX2ZpdGVkIDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoeWVhcixyZWdpb24pICU+JSAKICBzdW1tYXJpc2UodG90YWxfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09VCksLmdyb3VwcyA9ICJkcm9wIikKCiMgZ3JvdXAgYnkgc3RhdGUKc3RhdGVfZml0IDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUseWVhcixyZWdpb24pICU+JSAKICBzdW1tYXJpc2Uoc3RhdGVfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgbGVmdF9qb2luKHRvdGFsX2ZpdGVkLAogICAgICAgICAgICBieSA9IGMoInllYXIiLCJyZWdpb24iKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBzdGF0ZV92YWx1ZS90b3RhbF92YWx1ZSoxMDApCgojIFBsb3QgbWUKcCA8LSBnZ3Bsb3Qoc3RhdGVfZml0KSArCiAgZ2VvbV9hcmVhKAogICAgYWVzKAogICAgICB4ID0geWVhciwKICAgICAgeSA9IHJvdW5kKHBlcmNlbnRhZ2UpLAogICAgICBmaWxsID0gc3RhdGUKICAgICkKICApICsKICB5bGFiKCJQZXJjZW50YWdlICglKSIpICsKICAjIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcyhkaXNjcmV0ZSA9IFQsIGFscGhhID0gMC44KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgTXlGdW5jdGlvbnM6Om15X2dndGhlbWVfcCgpICsKICBmYWNldF93cmFwKH5yZWdpb24sIG5jb2wgPSAxKSArCiAgdGhlbWVfZGFyaygpCgpnZ3Bsb3RseShwLAogICAgICAgICBkeW5hbWljVGlja3MgPSBUUlVFKSAlPiUgCiAgbGF5b3V0KGhvdmVybW9kZSA9ICJ4IikgJT4lCiAgcmFuZ2VzbGlkZXIoKQoKYGBgCgojIyBBcmVhIHBsb3QgKHJ1bm5pbmcgbWVhbikKClRoaXMgZ3JhcGggc2hvd3MgdGhlIHByb3BvcnRpb24gb2YgZWFjaCBTdGF0ZSBzbW9vdGhlZCBvdmVyIGEgKjEwIHllYXJzIHJ1bm5pbmcgbWVhbioqLiBJdCBhbGxvd3MgdG8gYmV0dGVyIHNlZSBpbmNyZWFzaW5nIGFuZCBkZWNyZWFzaW5nIHRyZW5kcy4KCiMjIyBEeW5hbWljIGFnZ3JlZ2F0ZWQgcGxvdAoKKk5vdGU6KiBUaGlzIHBsb3QgaXMgYWxzbyBpbnRlcmFjdGl2ZSBhbmQgdGh1cywgZm9sbG93cyB0aGUgc2FtZSBvcHRpb25zIG9mIHRoZSBwcmV2aW91cyBvbmUuCgpgYGB7ciBhcmVhX3Bsb3QsIGV2YWwgPSBULCBlY2hvID0gVCwgZmlnLmhlaWdodCA9IDEwLCBmaWcud2lkdGggPSAxMH0KCiMgZ3JvdXAgYnkgc3RhdGUKc3RhdGVfZml0IDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUseWVhcixyZWdpb24sLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIHN1bW1hcmlzZShzdGF0ZV92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT0gVCksIC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICBsZWZ0X2pvaW4odG90YWxfZml0ZWQsCiAgICAgICAgICAgIGJ5ID0gYygieWVhciIsInJlZ2lvbiIpKSAlPiUKICBtdXRhdGUocGVyY2VudGFnZSA9IHN0YXRlX3ZhbHVlL3RvdGFsX3ZhbHVlKjEwMCkgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHJlZ2lvbikgJT4lIAogIG11dGF0ZShSTWVhbiA9IHpvbzo6cm9sbG1lYW4oeCA9IHBlcmNlbnRhZ2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybT1UKQogICAgKSAlPiUgIAogIGxlZnRfam9pbihzdGF0ZV9sYXQpCgojIFBsb3QgbWUKcCA8LSBnZ3Bsb3Qoc3RhdGVfZml0KSArCiAgZ2VvbV9hcmVhKAogICAgYWVzKAogICAgICB4ID0geWVhciwKICAgICAgeSA9IHJvdW5kKFJNZWFuKSwKICAgICAgZmlsbCA9IHN0YXRlCiAgICAgICMgZmlsbCA9IG9yZGVyCiAgICApCiAgKSArCiAgeWxhYigiMTAgeXJzIHJ1bm5pbmcgYXZlcmFnZSAoJSkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICAiU3RhdGUiLAogICAgdmFsdWVzID0gc3RhdGVfcGFsbGV0LAogICAgIyBsYWJlbHMgPSBzdGF0ZV9maXQgJT4lIGFycmFuZ2Uob3JkZXIpICU+JSAgcHVsbChzdGF0ZSkgJT4lIHVuaXF1ZSgpCiAgKSArCiAgTXlGdW5jdGlvbnM6Om15X2dndGhlbWVfcCgpICsKICBmYWNldF93cmFwKH5yZWdpb24sIG5jb2wgPSAxKSArCiAgdGhlbWVfZGFyaygpCgpzdXBwcmVzc1dhcm5pbmdzKApnZ3Bsb3RseShwLAogICAgICAgICBkeW5hbWljVGlja3MgPSBUUlVFKSAlPiUgCiAgbGF5b3V0KGhvdmVybW9kZSA9ICJ4IikgJT4lIAogICMgYWRkX3RyYWNlKCkgJT4lIAogIHJhbmdlc2xpZGVyKCkKKQoKYGBgCgojIyMgUGFwZXIgZmlndXJlOiBBZ2dyZWdhdGVkIFByb3BvcnRpb25hbCBjaGFuZ2UKCmBgYHtyIHBsb3RfYXJlYV9hdmVfYWdnLCBldmFsID0gRiwgZWNobyA9IEYsIHJlc3VsdHM9J2hpZGUnfQoKdG90YWxfZml0ZWQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieSh5ZWFyLHJlZ2lvbikgJT4lIAogIHN1bW1hcmlzZSh0b3RhbF92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT1UKSwuZ3JvdXBzID0gImRyb3AiKQoKCiMgZ3JvdXAgYnkgc3RhdGUKc3RhdGVfZml0IDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUseWVhcixyZWdpb24pICU+JSAKICBzdW1tYXJpc2Uoc3RhdGVfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgbGVmdF9qb2luKHRvdGFsX2ZpdGVkLAogICAgICAgICAgICBieSA9IGMoInllYXIiLCJyZWdpb24iKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBzdGF0ZV92YWx1ZS90b3RhbF92YWx1ZSoxMDApICU+JSAKICBncm91cF9ieShzdGF0ZSxyZWdpb24pICU+JSAKICBtdXRhdGUoUk1lYW4gPSB6b286OnJvbGxtZWFuKHggPSBwZXJjZW50YWdlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm09VCkKICAgICkgJT4lIAogICNPbmx5IHNob3cgcmVzdWx0cyBmb3Igc3ByaW5nCiAgZmlsdGVyKHN0cl9kZXRlY3QocmVnaW9uLCJTcHJpbmciKSwKICAgICAgICAgIWlzLm5hKFJNZWFuKSAjIFJlbW92ZSBOQXMgZnJvbSByb2xsbWVhbgogICAgICAgICApICU+JSAgCiAgbGVmdF9qb2luKHN0YXRlX2xhdCkKCiMgUGxvdCBtZQphZ2dfYXJlYSA8LSBnZ3Bsb3Qoc3RhdGVfZml0KSArCiAgZ2VvbV9hcmVhKAogICAgYWVzKAogICAgICB4ID0geWVhciwKICAgICAgeSA9IHJvdW5kKFJNZWFuKSwKICAgICAgZmlsbCA9IG9yZGVyCiAgICAgICMgZmlsbCA9IHN0YXRlCiAgICApCiAgKSArCiAgeWxhYigiUHJvcG90aW9uICgxMCB5cnMgcnVubmluZyBhdmVyYWdlKSIpICsKICAjIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcyhkaXNjcmV0ZSA9IFQsIGFscGhhID0gMC44KSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICAiU3RhdGUiLAogICAgdmFsdWVzID0gc3RhdGVfcGFsbGV0LAogICAgbGFiZWxzID0gc3RhdGVfZml0ICU+JSBhcnJhbmdlKG9yZGVyKSAlPiUgIHB1bGwoc3RhdGUpICU+JSB1bmlxdWUoKQogICkgKwogIG15X2dndGhlbWVfcChsZWdfcG9zID0gInJpZ2h0IikgKwogIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDEsImxpbmUiKSkKCgogIGdnc2F2ZShmaWxlbmFtZSA9ICJhcmVhX3Bsb3RfYXZnX2FnZy5qcGciLAogICAgICAgICBwbG90ID0gYWdnX2FyZWEsCiAgICAgICAgIHBhdGggPSBteV9wYXRoKCJSIiwiRmlndXJlcyIpLAogICAgICAgICB3aWR0aCA9IDgsCiAgICAgICAgIGhlaWdodCA9IDYKICApCgoKYGBgCgohW1Byb3BvcnRpb24gY2hhbmdlIGFnZ3JlZ2F0ZWQgYWxsIHNwZWNpZXMgbWFwIGZvciBwYXBlcl0oL1ZvbHVtZXMvRW50ZXJwcmlzZS9EYXRhL0Fjcm9zc0JvdW5kYXJpZXMvUmVzdWx0cy9GaWd1cmVzL2FyZWFfcGxvdF9hdmdfYWdnLmpwZykKCiMjIyBQYXBlciBmaWd1cmU6IFBlciBTcGVjaWVzIFByb3BvcnRpb25hbCBjaGFuZ2UKCmBgYHtyIHBhcGVyX3Bsb3RfYXJlYV9hdmVfc3BwLCBldmFsID0gRiwgZWNobyA9IEYsIHJlc3VsdHM9J2hpZGUnfQoKdG90YWxfZml0ZWQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieSh5ZWFyLHJlZ2lvbixzcHApICU+JSAKICBzdW1tYXJpc2UodG90YWxfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09VCksLmdyb3VwcyA9ICJkcm9wIikKCgojIGdyb3VwIGJ5IHN0YXRlCnN0YXRlX2ZpdCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHllYXIscmVnaW9uLHNwcCkgJT4lIAogIHN1bW1hcmlzZShzdGF0ZV92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT0gVCksIC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICBsZWZ0X2pvaW4odG90YWxfZml0ZWQsCiAgICAgICAgICAgIGJ5ID0gYygieWVhciIsInJlZ2lvbiIsInNwcCIpKSAlPiUKICBtdXRhdGUocGVyY2VudGFnZSA9IHN0YXRlX3ZhbHVlL3RvdGFsX3ZhbHVlKjEwMCkgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHJlZ2lvbixzcHApICU+JSAKICBtdXRhdGUoUk1lYW4gPSB6b286OnJvbGxtZWFuKHggPSBwZXJjZW50YWdlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm09VCkKICAgICkgJT4lIAogICNPbmx5IHNob3cgcmVzdWx0cyBmb3Igc3ByaW5nCiAgZmlsdGVyKHN0cl9kZXRlY3QocmVnaW9uLCJTcHJpbmciKSwKICAgICAgICAgIWlzLm5hKFJNZWFuKSAjIFJlbW92ZSBOQXMgZnJvbSByb2xsbWVhbgogICAgICAgICApICU+JSAgCiAgbGVmdF9qb2luKHN0YXRlX2xhdCkKCiMgUGxvdCBtZQpzc3BfYXJlYSA8LSBnZ3Bsb3Qoc3RhdGVfZml0KSArCiAgZ2VvbV9hcmVhKAogICAgYWVzKAogICAgICB4ID0geWVhciwKICAgICAgeSA9IHJvdW5kKFJNZWFuKSwKICAgICAgZmlsbCA9IG9yZGVyCiAgICAgICMgZmlsbCA9IHN0YXRlCiAgICApCiAgKSArCiAgeWxhYigiUHJvcG90aW9uICgxMCB5cnMgcnVubmluZyBhdmVyYWdlKSIpICsKICAjIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcyhkaXNjcmV0ZSA9IFQsIGFscGhhID0gMC44KSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICAiU3RhdGUiLAogICAgdmFsdWVzID0gc3RhdGVfcGFsbGV0LAogICAgbGFiZWxzID0gc3RhdGVfZml0ICU+JSBhcnJhbmdlKG9yZGVyKSAlPiUgIHB1bGwoc3RhdGUpICU+JSB1bmlxdWUoKQogICkgKwogIG15X2dndGhlbWVfcChsZWdfcG9zID0gImJvdHRvbSIpICsKICB0aGVtZShsZWdlbmQua2V5LndpZHRoID0gdW5pdCgxLCJsaW5lIikpICsgCiAgZmFjZXRfd3JhcCh+c3BwLCBuY29sID0gMSwgc3RyaXAucG9zaXRpb24gPSAicmlnaHQiKQoKCiAgZ2dzYXZlKGZpbGVuYW1lID0gImFyZWFfcGxvdF9hdmdfc3BwLmpwZyIsCiAgICAgICAgIHBsb3QgPSBzc3BfYXJlYSwKICAgICAgICAgcGF0aCA9IG15X3BhdGgoIlIiLCJGaWd1cmVzIiksCiAgICAgICAgIHdpZHRoID0gMTAsCiAgICAgICAgIGhlaWdodCA9IDEyCiAgKQoKCmBgYAohW1Byb3BvcnRpb24gY2hhbmdlIGFnZ3JlZ2F0ZWQgYWxsIHNwZWNpZXMgbWFwIGZvciBwYXBlcl0oL1ZvbHVtZXMvRW50ZXJwcmlzZS9EYXRhL0Fjcm9zc0JvdW5kYXJpZXMvUmVzdWx0cy9GaWd1cmVzL2FyZWFfcGxvdF9hdmdfc3BwLmpwZykKCiMjIEhpc3RvcmljIHF1b3RhIFZzIGRpc3RyaWJ1dGlvbnMKClRoaXMgc2VjdGlvbiBvZiB0aGUgcmVzdWx0cyBleHBsb3JlcyB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgaGlzdG9yaWMgZGlzdHJpYnV0aW9uIG9mIHRlIHN0b2NrIGFuZCB0aGUgaGlzdG9yaWMgcXVvdGEgYWxsb2NhdGlvbi4gV2UgY29sbGVjdGVkIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSB0b3RhbCBxdW90YSB0aGF0IGVhY2ggU3RhdGUgZ2V0cyBmb3IgZWFjaCBzcGVjaWVzLgoKUmlnaHQgbm93IHRoZSBhbmFseXNpcyBvbmx5IGNvdmVycyBibGFjayBzZWEgYmFzcywgc3VtbWVyIGZsb3VuZGVyIGFuZCBzY3VwLiBCdXQgd2UgY2FuIGdvIHNwZWNlaXMgYnkgc3BlY2llcyB0byBzZWUgd2hpY2ggb25lcyBoYXZlIHRoZWlyIHF1b3RhIGFsbG9jYXRlZCBieSBzdGF0ZSB0byBpbmNsdWRlIHRoZW0gaW4gdGhlIGFuYWx5c2lzLgoKLSBbQmxhY2sgU2VhIEJhc3M7ICpDZW50cm9wcmlzdGlzIHN0cmlhdGEqXShodHRwczovL3d3dy5tYWZtYy5vcmcvbmV3c2ZlZWQvMjAyMS9hc21mYy1hbmQtbWFmbWMtYXBwcm92ZS1ic2ItY29tbWVyY2lhbC1hbGxvY2F0aW9uLWNoYW5nZXMpCgoqKk5vdGU6KiogV2UgYXJlIHVzaW5nIHRoZSBuZXcgYWxsb2NhdGlvbnMgYmFzZWQgb24gdGhlIHN0b2NrJ3MgbW9zdCByZWNlbnQgYmlvbWFzcyBkaXN0cmlidXRpb24qIAoKLSBbU3VtbWVyIGZsb3VuZGVyXShodHRwOi8vd3d3LmFzbWZjLm9yZy91cGxvYWRzL2ZpbGUvNWY5YWY4MmEyMDE5U3VtbWVyRmxvdW5kZXJGTVBfUmV2aWV3LnBkZikKCi0gW1NjdXBdKGh0dHA6Ly93d3cuYXNtZmMub3JnL3VwbG9hZHMvZmlsZS81Zjk5ZDAxMTIwMTlfU2N1cF9GTVBfUmV2aWV3X2FwcHJvdmVkLnBkZikgU3VtbWVyIHBlcmlvZAoKRm9yIFN0YXRlLWxldmVsIG1hbmFnZWQgc3BlY2llcyBzZWUgdGhlIFtBdGxhbnRpYyBTdGF0ZXMgTWFyaW5lIEZpc2hlcmllcyBDb21pc3Npb25dKGh0dHA6Ly93d3cuYXNtZmMub3JnL2Zpc2hlcmllcy1tYW5hZ2VtZW50L3Byb2dyYW0tb3ZlcnZpZXcpIHdlYnNpdGUgYW5kIGdvIHNwZWNpZXMtYnktc3BlY2llcy4KCgpgYGB7ciBzdGF0ZV9xdW90YV90YmwsZXZhbD0gVCwgZWNobyA9IFR9CgpxdW90YV9hbGxvY2F0aW9uIDwtIHN0YXRlX2xhdCAlPiUgCiAgbXV0YXRlKAogICAgIkNlbnRyb3ByaXN0aXMgc3RyaWF0YSIgPSBjKAogICAgICAwLjAwNDAsICNNRQogICAgICAwLjAwNDAsICNOSAogICAgICAwLjE1NjQsICNNQQogICAgICAwLjEzMjMsICNSSQogICAgICAwLjAzNjcsICNDVAogICAgICAwLjA4NTcsICNOWQogICAgICAwLjIwMTAsICNOSgogICAgICAwLjA0MTEsICNERQogICAgICAwLjA4ODgsICNNRAogICAgICAwLjE2MTQsICNWQQogICAgICAwLjA4ODggI05DCiAgICApLAogICAgIlBhcmFsaWNodGh5cyBkZW50YXR1cyIgPSBjKAogICAgICAwLjAwMDQ3NTYsICNNRSAKICAgICAgMC4wMDAwMDQ2LCAjTkggCiAgICAgIDAuMDY4MjA0NiwgI01BIAogICAgICAwLjE1NjgyOTgsICNSSSAKICAgICAgMC4wMjI1NzA4LCAjQ1QgCiAgICAgIDAuMDc2NDY5OSwgI05ZIAogICAgICAwLjE2NzI0OTksICNOSiAKICAgICAgMC4wMDAxNzc5LCAjREUgCiAgICAgIDAuMDIwMzkxMCwgI01ECiAgICAgIDAuMjEzMTY3NiwgI1ZBCiAgICAgIDAuMjc0NDU4NCAjTkMKICAgICksCiAgICAiU3Rlbm90b211cyBjaHJ5c29wcyIgPSBjKAogICAgICAwLjAwMTIxMDEsICNNRQogICAgICAwLjAwMDAwMDAsICNITgogICAgICAwLjIxNTg3MjksICNNQQogICAgICAwLjU2MTk0NTYsICNSSQogICAgICAwLjAzMTUzOTksICNDVAogICAgICAwLjE1ODI0NjYsICNOWQogICAgICAwLjAyOTE2NjcsICNOSgogICAgICAwLjAwMDAwMDAsICNERQogICAgICAwLjAwMDExOTAsICNNRAogICAgICAwLjAwMTY1MDIsICNWQQogICAgICAwLjAwMDI0OTAgI05DCiAgICApCiAgKSAlPiUgCiAgZ2F0aGVyKCJzcHAiLCJxdW90YSIsNDo2KQoKIyBEb3VibGUgY2hlY2sgdGhleSBhbGwgYWRkIHRvIDEuLi4KcXVvdGFfYWxsb2NhdGlvbiAlPiUgCiAgZ3JvdXBfYnkoc3BwKSAlPiUgCiAgc3VtbWFyaXNlX2F0KHZhcnMocXVvdGEpLHN1bSkKCgpxdW90YV9hbGxvY2F0aW9uICU+JSAKICBhcnJhbmdlKG9yZGVyKSAlPiUgCiAgc2VsZWN0KC1vcmRlcikgJT4lIAogIHNwcmVhZChzcHAscXVvdGEpICU+JSAKICBrYWJsZSgpCmBgYAoKCiMjIyBHZXQgZGF0YSByZWFkeQoKYGBge3J9Cgp0b3RhbF9maXRlZCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHllYXIscmVnaW9uLHNwcCkgJT4lIAogIHN1bW1hcmlzZSh0b3RhbF92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT1UKSwuZ3JvdXBzID0gImRyb3AiKQoKIyBncm91cCBieSBzdGF0ZQpzdGF0ZV9maXQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieShzdGF0ZSx5ZWFyLHJlZ2lvbixzcHApICU+JSAKICBzdW1tYXJpc2Uoc3RhdGVfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgbGVmdF9qb2luKHRvdGFsX2ZpdGVkLAogICAgICAgICAgICBieSA9IGMoInllYXIiLCJyZWdpb24iLCJzcHAiKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBzdGF0ZV92YWx1ZS90b3RhbF92YWx1ZSoxMDApICU+JSAKICAjT25seSBzaG93IHJlc3VsdHMgZm9yIHNwcmluZwogIGZpbHRlcihzdHJfZGV0ZWN0KHJlZ2lvbiwiU3ByaW5nIikpCgpxdW90YV9kZiA8LSBxdW90YV9hbGxvY2F0aW9uICU+JSAKICBsZWZ0X2pvaW4oaGlzdG9yaWNfc3BwKSAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUsYWJyZXYseWVhcixyZWdpb24sc3BwLHF1b3RhKSAlPiUgCiAgc3VtbWFyaXNlKHN0YXRlX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPSBUKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIGxlZnRfam9pbih0b3RhbF9maXRlZCwKICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwicmVnaW9uIiwic3BwIikpICU+JQogIG11dGF0ZShEaXN0cmlidXRpb24gPSBzdGF0ZV92YWx1ZS90b3RhbF92YWx1ZSoxMDAsCiAgICAgICAgIEhpc3RvcmljID0gcXVvdGEqMTAwKSAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUscXVvdGEsc3BwKSAlPiUgCiAgbXV0YXRlKFJNZWFuID0gem9vOjpyb2xsbWVhbih4ID0gRGlzdHJpYnV0aW9uLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm09VCkKICAgICkgJT4lIAogICNPbmx5IHNob3cgcmVzdWx0cyBmb3Igc3ByaW5nCiAgZmlsdGVyKHN0cl9kZXRlY3QocmVnaW9uLCJTcHJpbmciKSwKICAgICAgICAgIWlzLm5hKFJNZWFuKSAjIFJlbW92ZSBOQXMgZnJvbSByb2xsbWVhbgogICAgICAgICApICU+JSAgCiAgbGVmdF9qb2luKHN0YXRlX2xhdCkgJT4lIAogIGZpbHRlcigKICAgICMgc3BwID09IkNlbnRyb3ByaXN0aXMgc3RyaWF0YSIKICAgIHNwcCAlaW4lIHF1b3RhX2FsbG9jYXRpb24kc3BwCiAgKQoKaGVhZChxdW90YV9kZikgJT4lIAogIGthYmxlKCkKYGBgCgojIyMgRXhwbG9yaW5nIGRpZmZlcmVudCB3YXlzIHRvIHNob3cgdGhlIHJlc3VsdHMKCiMjIyMgRGlmZmVyZW5jZSBsaW5lIHBsb3QKClRoaXMgdmVyc2lvbiBzaG93cyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBIaXN0b3JpYyBxdW90YSBhbGxvY2F0aW9uIGFuZCB0aGUgZGlzdHJpYnV0aW9uIHByb3BvcnRpb24gb2YgdGhlIHN0b2NrOgoKLSBkaWZmIDwgMCA9IHRoZSBkaXN0cmlidXRpb24gcHJvcG9ydGlvbiBpcyAqbGFyZ2VyKiB0aGFuIHRoZSBhbGxvY2F0ZWQgcXVvdGEKLSBkaWZmID4gMCA9IHRoZSBkaXN0cmlidXRpb24gcHJvcG9ydGlvbiBpcyAqc21hbGxlciogdGhhbiB0aGUgYWxsb2NhdGVkIHF1b3RhIAoKYGBge3J9CiMgT3B0aW9uIG9uZQoKcXVvdGFfZGYgJT4lCiAgbXV0YXRlKGRpZmYgPSBIaXN0b3JpYy0gRGlzdHJpYnV0aW9uLAogICAgICAgICBkaWZmX3JtZWFuID0gUk1lYW4tIERpc3RyaWJ1dGlvbikgJT4lIAogIGdhdGhlcigidHlwZSIsInZhbHVlIixkaWZmOmRpZmZfcm1lYW4pICU+JSAKICAjIFZpZXcoKQogIGdncGxvdCgpICsKICBnZW9tX2xpbmUoCiAgICBhZXMoCiAgICAgIHggPSB5ZWFyLAogICAgICB5ID0gdmFsdWUsCiAgICAgIGNvbG9yID0gb3JkZXIKICAgICkKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoIlN0YXRlIiwKICAgIHZhbHVlcyA9IHN0YXRlX3BhbGxldCwKICAgIGxhYmVscyA9IHF1b3RhX2RmICU+JSBhcnJhbmdlKG9yZGVyKSAlPiUgIHB1bGwoc3RhdGUpICU+JSB1bmlxdWUoKQogICAgKSArCiAgZmFjZXRfZ3JpZCh0eXBlfnNwcCwgCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9kYXJrKCkKCmBgYAojIyMjIExpbmV0eXBlIHBsb3QKCkhlcmUsIHdlIHBsb3QgdGhlIGRpc3RyaWJ1dGlvbmFsIHF1b3RhIChzb2xpZCBsaW5lcykgd2l0aCBlYWNoIFN0YXRlJ3MgYWxsb2NhdGlvbiB3aXRoIGRhc2hlZCAoLS0tLSkgbGluZXMKCmBgYHtyfQojIE9wdGlvbiBvbmUKCnF1b3RhX2RmICU+JSAKICBnYXRoZXIoImxldmVsIiwicXVvdGEiLERpc3RyaWJ1dGlvbjpSTWVhbikgJT4lIAogICMgbXV0YXRlKGRpZmYgPSBxdW90YV9wZXItIHBlcmNlbnRhZ2UpICU+JSAKICAjIFZpZXcoKQogIGdncGxvdCgpICsKICBnZW9tX2xpbmUoCiAgICBhZXMoCiAgICAgIHggPSB5ZWFyLAogICAgICB5ID0gcXVvdGEsCiAgICAgIGNvbG9yID0gb3JkZXIKICAgICkKICApICsKICBsYWJzKHggPSAiWWVhciIseSA9ICJRdW90YSAoJSkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoIlN0YXRlIiwKICAgIHZhbHVlcyA9IHN0YXRlX3BhbGxldCwKICAgIGxhYmVscyA9IHF1b3RhX2RmICU+JSBhcnJhbmdlKG9yZGVyKSAlPiUgIHB1bGwoc3RhdGUpICU+JSB1bmlxdWUoKQogICAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKCJTdGF0ZSIsCiAgICB2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQsCiAgICBsYWJlbHMgPSBxdW90YV9kZiAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkKICAgICkgKwogIHNjYWxlX2xpbmV0eXBlKCJRdW90YSIpICsKICBmYWNldF9ncmlkKHNwcCB+IGxldmVsKSsKICB0aGVtZV9kYXJrKCkKCmBgYAojIyMjIEVmZmljaWVuY3kgaW5kZXgKClRoZSBpZGVhIGhlcmUgaXMgY3JlYXRlIGFuZCAqZWZmaWNpZW5jeSBpbmRleCogKERhbmdlciEpIHRoYXQgY29tcHV0ZXMgdGhlIGFsaWdubWVudCBiZXR3ZWVuIHRoZSBkaXN0cmlidXRpb24gYW5kIHRoZSBhY3R1YWwgYWxsb2NhdGlvbi4gVGhlIGluZGV4IGlzIHNpbXBseTsKCiQkZWkgPSBcZnJhY3tIaXN0b3JpY1F1b3RhfXtEaXN0cmlidXRpb25Qcm9wb3J0aW9ufSQkIApTbywgaW4gY2FzZXMgd2hlcmUgKmVpKiA9IDEsIHRoZSBxdW90YSBpcyBhbGlnbmVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbjsgd2hlbiAqZWkqID4gMSB0aGVuIHRoZSBoaXN0b3JpYyBxdW90YSBpcyBtb3JlIHRoYW4gdGhlIHN0b2NrJ3MgU3RhdGUncyBkaXN0cmlidXRpb24sIGNvbnRyYXJpbHksICplaSogPCAxIG1lYW5zIHRoYXQgdGhlIGhpc3RvcmljIHF1b3RhIGlzIGxlc3MgdGhhbiB3aGF0IHRoZSBTdGF0ZSBjdXJyZW50bHkgaGFzLgoKCioqTm90ZToqKiAKLSBUaGVyZSBhcmUgc29tZSBjcmF6enkgb3V0bGllcnMgdGhhdCBoYXZlIGJlZW4gcmVtb3ZlZCwgZm9yIG5vdy4uLiAKLSBCb3R0b20gcGxvdCByZXByZXNlbnRpbmcgaW5kZXggYXMgYSBSbWVhbgoKIyMjIyMgQXMgYSBub3JtYWwgeWVhciB0byB5ZWFyCgpgYGB7cn0KIyBPcHRpb24gb25lCgplZmZfaW5kZXggPC0gcXVvdGFfZGYgJT4lIAogICMgZmlsdGVyKAogICMgICBzcHAgPT0iQ2VudHJvcHJpc3RpcyBzdHJpYXRhIgogICMgKSAlPiUgCiAgbXV0YXRlKGluZGV4ID0gRGlzdHJpYnV0aW9uL0hpc3RvcmljLAogICAgICAgICBpbmRleF9ybWVhbiA9IFJNZWFuL0hpc3RvcmljKSAlPiUKICBnYXRoZXIoImxldmVsIiwiaW5kZXgiLGluZGV4OmluZGV4X3JtZWFuKSAlPiUKICBmaWx0ZXIoaW5kZXggPCA1KSAjIHRoZXJlIGFyZSBzb21lIGNyYWFhYXp5IG91dGxpZXJzCiAgIyBWaWV3KCkKICAKZ2dwbG90KGVmZl9pbmRleCkgKwogIGdlb21fbGluZSgKICAgIGFlcygKICAgICAgeCA9IHllYXIsCiAgICAgIHkgPSBpbmRleCwKICAgICAgY29sb3IgPSBzdGF0ZQogICAgKSwKICApICsKICBsYWJzKHggPSAiWWVhciIseSA9ICJFZmZpY2llbmN5IGluZGV4IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKCJTdGF0ZSIsCiAgICB2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQsCiAgICBsYWJlbHMgPSBxdW90YV9kZiAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkKICAgICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgiU3RhdGUiLAogICAgdmFsdWVzID0gc3RhdGVfcGFsbGV0LAogICAgbGFiZWxzID0gcXVvdGFfZGYgJT4lIGFycmFuZ2Uob3JkZXIpICU+JSAgcHVsbChzdGF0ZSkgJT4lIHVuaXF1ZSgpCiAgICApICsKICBmYWNldF9ncmlkKGxldmVsfnNwcCwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlIikrCiAgdGhlbWVfZGFyaygpCgpgYGAKCg==